DAO – Data Access Object – Pattern – CRUD – Oracle – IBM DB2 – MSSQL Server – C#

Publicado: 11 de dezembro de 2014 em C#

No ciência da computação, Data Access Object é um padrão para um objeto que fornece uma interface abstrata para algum tipo de banco de dados ou outro mecanismo de persistência e que permite separar regras de negócio das regras de acesso a banco de dados. A vantagem de usar objetos de acesso a dados é a separação simples e rigorosa entre duas partes importantes de uma aplicação que não devem e não podem conhecer quase que nada uma da outra, e que podem evoluir frequentemente e independentemente.

O DAO implementa o mecanismo de acesso necessário para trabalhar com a fonte de dados. A fonte de dados pode ser um armazenamento persistente como um RDBMS, um serviço externo, como uma troca de B2B, um repositório como um banco de dados LDAP, um serviço de negócios acessado via CORBA, Internet Inter-ORB Protocol (IIOP) ou soquetes de baixo nível. O componente de negócio que se baseia no DAO usa a interface mais simples exposta pelo DAO para seus clientes.

Microsoft, C# e DAO

O DAO Pattern J2EE não deve ser confundido com o DAO método de acesso a dados da Microsoft . O DAO (Microsoftfornece um quadro para a utilização de código para criar e manipular bancos de dados através de um conjunto hierárquico de objetos que usam o mecanismo de banco de dados Microsoft Jet para arquivos MDB, ou através de ODBC ou também banco de dados IASM como o antigo DBase, Paradox entre outros. O DAO Microsoft é considerado obsoleto e não é suportado pelo .NET Framework.

Devido a similaridade do C# com o Java é possível utilizar integralmente o DAO Pattern que é um padrão já consagrado por desenvolvedores Java para separar a camada de negocio da camada do banco de dados. O DAO é um célebre Pattern utilizado sozinho ou também em conjunto com outros frameworks, provavelmente alguns desenvolvedores C# já o utilizaram de algum modo, implicitamente ou explicitamente, mesmo sem o conhecer em detalhes.

DAO - CRUD - C#

DAO – CRUD – C#

DAO Pattern

O DAO é um padrão flexível e não uma regra ele é utilizado em conjunto com Factory Pattern e Broker Pattern (veja Patterns relacionados no link abaixo) por isto é comum você encontrar algumas variações de sua implementação, o padrão possui quatro especificações para que possa ser utilizado corretamente elas são: DataAccessObject, DataSourceObject, BussinesObject e TransferObject.

  1. DataAccessObjecté o objeto principal desse padrão. O Data Access Object abstrai a implementação fundamental de acesso a dados para o Business Objects para permitir acesso transparente à fonte de dados.
  2. DataSourceObjectrepresenta uma implementação da fonte de dados. Uma fonte de dados pode ser uma base de dados tal como um RDBMS, repositório XML, e assim por diante.
  3. BussinesObject – o objeto de negócios representa o dados do cliente. É o objeto que requer acesso à fonte de dados para obter e armazenar dados.
  4. TransferObjectrepresenta um objeto de transferência usado como um suporte de dados. O Data Access Object pode usar um objeto de transferência para retornar dados para o cliente. O Data Access Object também pode receber os dados do cliente em um objeto de transferência para atualizar os dados na fonte de dados.

DAO Pattern: http://www.oracle.com/technetwork/java/dataaccessobject-138824.html

CRUD – DAO

CRUD acrónimo de Create, Read, Update e Delete, utiliza as quatro operações básicas  para criação, consulta, atualização e exclusão de dados.

Através do padrão DAO vamos utilizar as operações CRUD para manipular dados no banco de dados. O DAO é um Patter J2EE, mas como ele separa as regras de negocio do acesso a dados também podemos utiliza-lo com qualquer tipo de interface, seja pela linha de comando, uma GUI desktop ou aplicações web.

Para usar o DAO você utiliza o Factory Pattern para criar uma abstração para o acesso a dados e uma classe concreta para seu tipo de acesso como por exemplo OracleDAOFactory, DB2DAOFactory e assim por diante. Então você pode criar a interface para seu objeto DAO chamada DAOFuncionario e a partir da interface você pode criar as classes DAO como, DAOFuncionarioOracle, DAOFuncionarioDB2 e utilizar o objeto de transferência para manipular os dados.

Neste exemplo não criamos uma classe abstrata utilizando o Pattern Factory, cortamos caminho pois utilizamos apenas um objeto DAO para todos os bancos de dados, mas caso deseje criar uma abstração para classes concretas para cada banco de dados siga a especificação oficial do DAO Pattern no link logo acima.

Visual Studio

Crie um design como na figura abaixo, utilizando 3 Panels, 7 Labels, 6 TextBox e 5 Buttons:

Design Time

Design Time

Atente-se a organização dos Namespaces para cada classe e os drivers utilizados para cada banco de dados.

Exemplo:

Neste exemplo usamos o Pattern DAO para criar operações CRUD utilizando uma interface gráfica, como este exemplo não possuí uma tela de login mude o acesso ao banco e usuário e senha diretamente na classe FuncionarioDAO.

Este é o terceiro método que disponibilizamos para manipular dados através de um banco de dados, para ver este mesmo programa utilizando SQL direto da aplicação clique aqui.

Pare ver este programa usando objetos no banco de dados como Views e Triggers clique aqui ou procure na busca também por Stored Procedures e cursores.

Ainda veremos outros métodos para manipular dados através de frameworks específicos como Entity Framework e outros.

SQL

Oracle

-- Cria tabela de funcionarios
create table Funcionarios(
  ID_Funcionario  NUMBER(5),
  Nome            VARCHAR2(30),
  Sobrenome       VARCHAR2(70),
  Cargo           VARCHAR2(30),
  Salario         NUMBER(9,2));

DB2

-- Cria tabela de funcionarios
create table Funcionarios (
    ID_Funcionario  INTEGER,
    Nome            VARCHAR(30),
    Sobrenome       VARCHAR(70),
    Cargo           VARCHAR(30),
    Salario         NUMERIC(9,2));

MSSQL

-- Cria tabela de funcionarios
create table Funcionarios (
   ID_Funcionario  Int,
   Nome            VARCHAR(30),
   Sobrenome       VARCHAR(70),
   Cargo           VARCHAR(30),
   Salario         Decimal(9,2));

C#

Objeto – Funcionario

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesenvolvimentoAberto.Modelo
{
    class Funcionario
    {
        // Declara atributos
        private long id;
        private string nome;
        private string sobrenome;
        private string cargo;
        private double salario;

        // Declara construtor padrão
        public Funcionario()
        {

        }

        // Declara construtor overload
        public Funcionario(long id, string nome, string sobrenome,
            string cargo, double salario)
        {
            this.id = id;
            this.nome = nome;
            this.sobrenome = sobrenome;
            this.cargo = cargo;
            this.salario = salario;
        }

        // Declara propriedades
        // Caso deseje pode utilizar metodos Getter e Setters
        public long Id
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }
        public string Nome
        {
            get
            {
                return nome;
            }
            set
            {
                nome = value;
            }
        }
        public string Sobrenome
        {
            get
            {
                return sobrenome;
            }
            set
            {
                sobrenome = value;
            }
        }
        public string Cargo
        {
            get
            {
                return cargo;
            }
            set
            {
                cargo = value;
            }
        }
        public double Salario
        {
            get
            {
                return salario;
            }
            set
            {
                salario = value;
            }
        }

    }
}

Factory Pattern – DAConexaoFactory

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Data.SqlClient;    // ADO.NET
using Oracle.DataAccess.Client; // ODAC 12c
using IBM.Data.DB2;             // IBM Data Server Provider

using System.Data.Common;       // DbProviderFactory

namespace DesenvolvimentoAberto.Conexao
{

    class DACconexaoFactory : DbProviderFactory
    {
        // Cria objetos de conexão
        private static string connectionString;
        private static DbConnection connUnica = null;
        private static Exception erro;

        // Define tipos de datasource
        public static readonly int ORACLE = 1;
        public static readonly int DB2 = 2;
        public static readonly int MSSQL = 3;

        // Define Driver
        private static System.Data.Common.DbProviderFactory factory;

        // cria conexões
        // você pode alimentar o nome do servidor, timeout e banco de dados
        // de alguma configuração global ou como achar melhor.

        public static DbConnection getConexao(int fabrica, string usuario, string senha)
        {
           factory = new DACconexaoFactory();

           if (fabrica == ORACLE)
            {
                try
                {
                    // String de Conexao
                    connectionString = 

                    // Usuario
                    "User Id=" + usuario + 

                    // Senha
                    ";Password=" + senha + 

                    // TNSnames
                    ";Data Source=xe";

                    // ODAC 12c
                    factory =  DbProviderFactories.GetFactory("Oracle.DataAccess.Client");

                    connUnica = factory.CreateConnection();
                    connUnica.ConnectionString = connectionString;
                    connUnica.Open();
                }

                 catch (Exception ex)
                {
                    erro = ex;
                }
            }

           if (fabrica == DB2)
           {
               try
               {
                   // String de Conexao
                   connectionString =

                   // Servidor
                   "Server=localhost" +

                   // Banco de dados
                   ";Database=DEVA" + 

                   // Usuario
                   ";UID=" + usuario +

                   // Senha
                   ";PWD=" + senha +

                   // TNSnames
                   ";Connect Timeout=40";

                   // IBM DATA Server Provider
                   factory = DbProviderFactories.GetFactory("IBM.Data.DB2");

                   connUnica = factory.CreateConnection();
                   connUnica.ConnectionString = connectionString;
                   connUnica.Open();
               }

               catch (Exception ex)
               {
                   erro = ex;
               }
           }

           if (fabrica == MSSQL)
           {
               try
               {
                   // String de Conexao
                   connectionString =

                   // Servidor
                   "Server=localhost" + 

                   // Banco de dados
                   ";Database=DevAberto" + 

                   // Usuario
                   ";UID=" + usuario +

                   // Senha
                   ";PWD=" + senha +

                   // TNSnames
                   ";Connect Timeout=40";

                   // ADO NET Nativo - MSSQL Server
                   factory = DbProviderFactories.GetFactory("System.Data.SqlClient");

                   connUnica = factory.CreateConnection();
                   connUnica.ConnectionString = connectionString;
                   connUnica.Open();
               }

               catch (Exception ex)
               {
                   erro = ex;
               }
           }
            return  connUnica;
        }

        // Recupera Driver
        public static DbProviderFactory getFactory()
        {
            return factory;
        }
        // Recupera Erro
        public static Exception getErro()
        {
            return erro;
        }

    }
}

Interface – IFuncionarioDAO

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using DesenvolvimentoAberto.Modelo;

namespace DesenvolvimentoAberto.Dao
{
    interface IFuncionarioDAO
    {
        // Cria interface
        // A interface propricia os retornos corretos de cada operação.

        Funcionario buscaFuncionario(string id);

        Boolean insereFuncionario(Funcionario funcionario);

        Boolean updateFuncionario(Funcionario funcionario);

        Boolean deletaFuncionario(Funcionario funcionario);

        // TODO: Insira outros metodos que você deseje que sejam obrigatorios.

    }
}

Objeto DAO – FuncionarioDAO

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Common;
using System.Data.SqlTypes;

using DesenvolvimentoAberto.Conexao;
using DesenvolvimentoAberto.Modelo;

namespace DesenvolvimentoAberto.Dao
{
    class FuncionarioDAO : IFuncionarioDAO
    {
        // Declara objetos
        private DbConnection conn;
        private Exception erro;
        private string sql;

        public FuncionarioDAO()
        {
            // Como o exemplo não possui uma tela de login
            // utilizamos uma adaptação no construtor da classe
            // você pode utilizar um login para que o factory da conexão
            // use a string de conexão completa.

            try
            {
                this.conn = DACconexaoFactory.getConexao(1, "user", "password");
            }
            catch
            {
                erro = DACconexaoFactory.getErro();
            }

        }
        public Modelo.Funcionario buscaFuncionario(string id)
        {
            // Cria objeto
            Funcionario funcionario = new Funcionario();

            sql = sql = "SELECT * FROM FUNCIONARIOS WHERE ID_FUNCIONARIO = " + id;

            try
            {
                // Cria Conexão Driver especifico
                DbCommand cmd = DACconexaoFactory.getFactory().CreateCommand();
                cmd.Connection = conn;
                cmd.CommandText = sql;
                cmd.ExecuteNonQuery();

                // Cria set de dados
                DbDataReader dados = cmd.ExecuteReader();

                // Converte Decimal para Double para IBM DB2 e MSSQL
                if (dados.HasRows)
                {
                    while (dados.Read())
                    {
                        funcionario.Id = dados.GetInt32(0);
                        funcionario.Nome = dados.GetString(1);
                        funcionario.Sobrenome = dados.GetString(2);
                        funcionario.Cargo = dados.GetString(3);
                        funcionario.Salario = Convert.ToDouble(dados.GetDecimal(4));
                    }
                }

            }
            catch (Exception ex)
            {
                // Retorna erro
                erro = ex;
            }
            return funcionario;
        }

        public bool insereFuncionario(Modelo.Funcionario funcionario)
        {
            // Define SQL
            // Troca decimal é requerido se Oracle/DB2 for ptbr.
            sql = "INSERT INTO FUNCIONARIOS VALUES ("
                + funcionario.Id + ", '" +
                  funcionario.Nome + "', '" +
                  funcionario.Sobrenome + "', '" +
                  funcionario.Cargo + "', " +
                  trocaDecimal(Convert.ToString(funcionario.Salario)) + ")";

            try
            {
                // Cria Conexão Driver especifico
                DbCommand cmd = DACconexaoFactory.getFactory().CreateCommand();
                cmd.Connection = conn;
                cmd.CommandText = sql;

                cmd.ExecuteNonQuery();
                conn.Close();
                return true;
            }
            catch (Exception ex)
            {
                // Retorna erro
                erro = ex;
            }

            return false;
        }

        public bool updateFuncionario(Modelo.Funcionario funcionario)
        {
            // Define SQL
            sql = "UPDATE FUNCIONARIOS SET " +
                "ID_FUNCIONARIO = " + funcionario.Id + ", " +
                "NOME = '" + funcionario.Nome + "', " +
                "SOBRENOME = '" + funcionario.Sobrenome + "', " +
                "CARGO = '" + funcionario.Cargo + "', " +
                "SALARIO = " + trocaDecimal(Convert.ToString(funcionario.Salario)) +
                "WHERE ID_FUNCIONARIO = " + funcionario.Id;
            try
            {
                // Cria Conexão Driver especifico
                DbCommand cmd = DACconexaoFactory.getFactory().CreateCommand();
                cmd.Connection = conn;
                cmd.CommandText = sql;

                cmd.ExecuteNonQuery();
                conn.Close();
                return true;
            }
            catch (Exception ex)
            {
                // Retorna erro
                erro = ex;
            }

            return false;
        }

        public bool deletaFuncionario(Modelo.Funcionario funcionario)
        {
            // Define SQL
            sql = "DELETE FROM FUNCIONARIOS WHERE ID_FUNCIONARIO = " + funcionario.Id;

            try
            {
                // Cria Conexão Driver especifico
                DbCommand cmd = DACconexaoFactory.getFactory().CreateCommand();
                cmd.Connection = conn;
                cmd.CommandText = sql;

                cmd.ExecuteNonQuery();
                conn.Close();
                return true;
            }
            catch (Exception ex)
            {
                // Retorna erro
                erro = ex;
            }

            return false;
        }

        private static String trocaDecimal(string conteudo)
        {
            // Substitui decimal na manipulação de SQL
            return conteudo.Replace(",", ".");
        }

        // Retorna erro
        public string getErro()
        {
            return erro.ToString();
        }
    }
}

GUI – Aplicação – Windows Form

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using DesenvolvimentoAberto.Modelo;
using DesenvolvimentoAberto.Dao;

namespace DACampos
{

    public partial class Campos : Form
    {

        public Campos()
        {
            InitializeComponent();
        }

        // Utiliza DAO

        // Evento de clique do botão Pesquisar
        private void button1_Click(object sender, EventArgs e)
        {
            // Cria objeto
            Funcionario funcionario = new Funcionario();

            // Executa busca
            funcionario = new FuncionarioDAO().buscaFuncionario(textBox6.Text);

            // Verifica resultado
            long resultado = funcionario.Id;

            if (resultado != 0)
            {
                textBox1.Text = Convert.ToString(funcionario.Id);
                textBox2.Text = funcionario.Nome;
                textBox3.Text = funcionario.Sobrenome;
                textBox4.Text = funcionario.Cargo;
                textBox5.Text = Convert.ToString(funcionario.Salario);
            }
            else
            {
                MessageBox.Show("Funcionário não encontrado!");
                textBox6.Focus();
                textBox6.SelectAll();
            }

        }

        private static String trocaDecimal(string conteudo)
        {
            // Substitui decimal na manipulação de SQL
            return conteudo.Replace(".", ",");
        }

        // Novo registro
        private void button2_Click(object sender, EventArgs e)
        {
            // Limpa componentes
            textBox1.Text = null;
            textBox2.Text = null;
            textBox3.Text = null;
            textBox4.Text = null;
            textBox5.Text = null;

            // Define foco
            textBox1.Focus();
        }

        // Insere registro
        private void button3_Click(object sender, EventArgs e)
        {
            // Cria objeto do modelo usando o construtor overload
            Funcionario funcionario = new Funcionario(Convert.ToInt32(textBox1.Text),
                textBox2.Text, textBox3.Text, textBox4.Text, Convert.ToDouble(trocaDecimal(textBox5.Text)));

            // cria objeto DAO
            FuncionarioDAO inserir = new FuncionarioDAO();

            // Insere objeto
            Boolean resultado = inserir.insereFuncionario(funcionario);

            // Verifica resultado
            if (resultado)
            {
                MessageBox.Show("Dados inseridos com sucesso");
            }
            else
            {
                MessageBox.Show("Erro ao inserir dados:" + Environment.NewLine +
                    Environment.NewLine +
                    inserir.getErro());
            }

        }

        // Altera registro
        private void button4_Click(object sender, EventArgs e)
        {
            // Cria objeto do modelo usando o construtor overload
            Funcionario funcionario = new Funcionario(Convert.ToInt32(textBox1.Text),
               textBox2.Text, textBox3.Text, textBox4.Text, Convert.ToDouble(trocaDecimal(textBox5.Text)));

            // Cria objeto DAO
            FuncionarioDAO alterar = new FuncionarioDAO();

            // Altera Objeto
            Boolean resultado = alterar.updateFuncionario(funcionario);

            // Verifica resultado
            if (resultado)
            {
                MessageBox.Show("Dados alterados com sucesso");
            }
            else
            {
                MessageBox.Show("Erro ao alterar dados:" + Environment.NewLine +
                    Environment.NewLine +
                    alterar.getErro());
            }
        }

        // Deleta registro
        private void button5_Click(object sender, EventArgs e)
        {
            // Cria objeto do modelo usando o construtor overload
            Funcionario funcionario = new Funcionario(Convert.ToInt32(textBox1.Text),
               textBox2.Text, textBox3.Text, textBox4.Text, Convert.ToDouble(trocaDecimal(textBox5.Text)));

            // Cria objeto DAP
            FuncionarioDAO apagar = new FuncionarioDAO();

            // Deleta objeto
            Boolean resultado = apagar.deletaFuncionario(funcionario);

            // verifica resultado
            if (resultado)
            {
                MessageBox.Show("Dados apagados com sucesso");
                button2.PerformClick();
                textBox6.Focus();
            }
            else
            {
                MessageBox.Show("Erro ao alterar dados:" + Environment.NewLine +
                    Environment.NewLine +
                    apagar.getErro());
            }
        }
    }
}

 

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s