JBoss Enterprise Application Platform – Java

Publicado: 21 de dezembro de 2014 em Java

O JBoss Enterprise Application Platform é uma plataforma de código aberto baseada em Java EE de execução do servidor de aplicativos baseado em assinatura usado para criação, implantação e hospedagem de aplicações e serviços Java altamente transacionais.  O JBoss Enterprise Application Platform é parte do portfólio JBoss Enterprise Middleware de software. Como é baseado em Java, o servidor de aplicações JBoss opera em varias plataformas e pode ser utilizado em qualquer sistema operacional que suporte Java. O JBoss Enterprise Application Platform foi desenvolvido pela JBoss, atualmente uma divisão da Red Hat.

JBoss Enterprise Application Platform: http://jbossas.jboss.org/downloads

Instalando e testando o JBoss EAP

1 – Baixe o JBoss EAP e descompacte-o em uma pasta de sua preferencia:

JBoss - EAP -Download

JBoss – EAP -Download

2 – O JBoss EAP roda na porta 8080, caso já possua um servidor rodando nesta mesma porta, você precisa reconfigurar a portar para o JBoss. No diretório de sua instalação standalone\configuration abra o arquivo standoalone.xml e mude as portas, utilize a imagem abaixo para referencia. Caso não tenha nenhum outro servidor utilizando a porta 8080 ignore este passo:

Reconfigurando porta

Reconfigurando porta

3 – Na pasta bin do seu servidor rode o arquivo standalone.bat através da linha de comando:

JBoss: Instancia StandAlone

JBoss: Instancia StandAlone

4 – Abra o seu navegador e use digite o endereço do servidor local na porta que você configurou:

JBoss - Localhost:5080

JBoss – Localhost:5080

Pronto! Seu servidor JBoss já esta funcionando corretamente, você pode instalar o JBoss Developer Studio ou as ferramentas para o Eclipse e criar suas aplicações. Para saber como instalar o JBoss Tools for Eclipse clique aqui.

O Apache Maven é uma ferramenta de gerenciamento de projetos e compressão indispensável no gerenciamento de projetos de todos os tamanhos. O Maven também torna o trabalho do desenvolvedor muito mais fácil quando você precisa utilizar frameworks e bibliotecas diversas que não estão incluídos por padrão no pacote Java que você utiliza. Para começar a fazer uso dos recursos que o Maven nos proporciona vamos utilizar o framework Hibernate e uma biblioteca de acesso a dados da Oracle para criar uma simples aplicação web com o servidor de aplicação Tomcat.

O que é Hibernate?

O Hibernate é um framework para o mapeamento objeto-relacional escrito na linguagem Java, que facilita o mapeamento dos atributos entre uma base tradicional de dados relacionais e o modelo do objeto de uma aplicação, mediante o uso de arquivos (XML) ou anotações Java.

Hibernate: http://hibernate.org/

Configurando o Eclipse e o Maven para criar uma aplicação Web

Nosso foco principal é mostrar como utilizar o Maven para adicionar dependências e mostrar como funciona os pacotes que o Maven utiliza sem que tenhamos que baixa-los e instala-los e também como configurar o Eclipse para que o Tomcat consiga trabalhar em conjunto com o Maven. Não se preocupe em entender todo o código abaixo pois não focaremos em como utilizar o Hibernate agora, futuramente teremos vários outros posts que o contemplarão.

1 – Crie um projeto Maven com o artefato maven-archetype-webapp e o configure adicionado o servidor Tomcat ao Build Path, caso não saiba como fazer isto veja nosso post anterior sobre como utilizar o Maven e o Tomcat clicando aqui.

  • Com o projeto criado, clique com o botão direito no seu projeto e escolha Maven->Add Dependency.
  • Digite a palavra hibernate e encontre org.hibernate hibernate-core.
  • Expanda e selecione sua ultima versão final.
Hibernate Core

Hibernate Core

2 – Por padrão os downloads estão desabilitados, precisamos habilita-los para podermos utilizar outras dependências. No menu Window->Preferences digite “maven” e posicione o cursor no tópico Maven e marque os tópicos como na figura abaixo e aguarde o download, talvez precise reinicializar o Eclipse:

Maven - Preferencias

Maven – Preferencias

3 – Após o carregamento completo das configurações do Eclipse, continue a adicionar mais dependências, desta vez escolha hibernate-validator:

Hibernate Validator

Hibernate Validator

4 – Em seguida adicione hibernate Entity-manager:

Hibernate Entity Manager

Hibernate Entity Manager

5 – Por ultimo adicione Oracle ojdbc14:

Oracle - ojdbc14

Oracle – ojdbc14

6 – Agora abra seu arquivo chamado pom.xml e constatará que ocorreu um erro ao adicionar o driver da Oracle, isto porque o Maven não consegue baixa-lo. Você precisa de um Login gratuito da Oracle para baixar o driver e precisa instala-lo manualmente no Maven, utilize o link abaixo para baixar o arquivo:

ojdbc14: http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-10201-088211.html

Para instalar utilize a linha de comando abaixo, atente-se as versões no arquivo pom.xml:

mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14  -Dversion=10.2.0.4.0 -Dpackaging=jar -Dfile=ojdbc14.jar -DgeneratePom=true

Use a imagem abaixo para referencia de como instalar a dependência:

Oracle - ojdbc14

Oracle – ojdbc14

Após instalar com sucesso volte ao Eclipse, clique com o botão direito no seu projeto e escolha Maven->Update Project o erro deve desaparecer.

7 – O Tomcat por padrão não consegue utilizar as dependências que o Maven possui, você precisa mudar a configuração. Com o botão direito no seu projeto escolha propriedades e Deployment Assembly:

  • Clique em Add.
  • Escolha Java Build Path Entries.
  • Escolha Maven Dependencies e finalize.
Web Deployment Assembly

Web Deployment Assembly

8 – Crie os arquivos para cada código abaixo e rode sua aplicação utilizando o Hibernate para ler um registro do banco de dados:

Maven - Tomcat - Hibernate - Oracle

Maven – Tomcat – Hibernate – Oracle

Exemplo:

Neste exemplo utilizamos o Maven para localizar as dependências necessárias para nosso projeto sem que precisássemos instala-las manualmente. Crie cada arquivo com seu respectivo tipo, utilize a imagem acima para verificar como fica a arvore do seu projeto. Rode o Servlet chamado HelloWorldHibernate.java.

Oracle

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

-- Insere dados na tabela
INSERT INTO FUNCIONARIOS VALUES  (10, 'John', 'Lennon', 'Compositor', 1234.55);

XML – hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">pass</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.current_session_context_class">thread</property>

<mapping class="org.desenvolvimento.aberto.Funcionario" />

</session-factory>
</hibernate-configuration>

Java

Servlet – Hello World Hibernate

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Session;

public class HelloWorldHibernate extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public HelloWorldHibernate() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Abre sessão recuperando a conexão
		Session session = HibernateFactory.getSessionFactory().openSession();

		// Inicia transação
		session.beginTransaction();

		// Cria objeto de negocio
		Funcionario funcionario = new Funcionario();

		// Adiciona sessão ao objeto
		funcionario = (Funcionario) session.load(Funcionario.class, 10);

		// Cria conteudo HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		// Retorna valores do objeto
		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto</h1>");
		html.println("<h2>Maven - Dependências ADD: Hibernate Framework: </h2>");
		html.println(funcionario.getId() + " - ");
		html.println(funcionario.getNome() + " ");
		html.println(funcionario.getSobrenome() + " - ");
		html.println(funcionario.getCargo() + " - ");
		html.println(funcionario.getSalario());
		html.println("</body>");
		html.println("</html>");

		// Encerra sessão
		session.getTransaction().commit();

	}

}

Hibernate – Session Factory

package org.desenvolvimento.aberto;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateFactory {

	// Cria objeto da sessão
	private static final SessionFactory sessionFactory = buildSessionFactory();

	// Constroi sessão
	private static SessionFactory buildSessionFactory() {
		try {
			// buildSessionFactory não será utilizado em versões superiores
			// Veremos outros métodos para criar um Factory
			// Não é necessário incluir o "hibernate.cfg.xml" no configure()
            // Incluímos somente a nível de fácil entendimento da chamada da configuração.
			// Você pode retirar a chamada.
			return new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
		} catch (Throwable ex) {
			// Em caso de erro
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	// Retorna Factory da sessão
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	// Encerra Sessão
	public static void shutdown() {
		getSessionFactory().close();
	}

}

Objeto de negocio – Funcionário

package org.desenvolvimento.aberto;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

// Define Entidade e tabela
@Entity
@Table(name = "funcionarios")
public class Funcionario {

	// Define atributos e decoradores Hibernate como ID e colunas
	@Id
	@GeneratedValue
	@Column(name = "ID_FUNCIONARIO")
	private int id;

	@Column(name = "NOME")
	private String nome;

	@Column(name = "SOBRENOME")
	private String sobrenome;

	@Column(name = "CARGO")
	private String Cargo;

	@Column(name = "SALARIO")
	private double salario;

	// Métodos Getter e Setter
	public long getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getSobrenome() {
		return sobrenome;
	}

	public void setSobrenome(String sobrenome) {
		this.sobrenome = sobrenome;
	}

	public String getCargo() {
		return Cargo;
	}

	public void setCargo(String cargo) {
		Cargo = cargo;
	}

	public double getSalario() {
		return salario;
	}

	public void setSalario(double salario) {
		this.salario = salario;
	}

}

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.

ABAP e DAO

O ABAP Objects possui conceitos comuns com o Java e utilizar o DAO Pattern que é um método padrão já consagrado para separar a camada de negocio da camada do banco de dados facilita muito a legibilidade e organização do código ABAP, visto que o SAP R/3 já comtempla uma arquitetura propicia em três camadas e um ambiente estabelecido onde podemos cortar certos caminhos, tornado simples, fácil e até mesmo divertido criar este tipo de programação, pois na pratica você tem uma classe para o objeto de negocio que contem as regras para cada método do objeto e uma classe para o objeto de dados que é responsável por manipular os dados no banco de dados e negocia-lo com o objeto de transferência que fica responsável pela comunicação com a interface de usuário.

O ABAP possui a vantagem de que não precisamos aplicar o Pattern Factory Method ao DAO, pois o Open SQL já nos possibilita uma função semelhante e podemos utiliza-lo em nosso objeto DAO, a vantagem é que outros desenvolvedores que utilizarão seu código já saberão onde está a regra e onde está a funcionalidade de acesso a dados e também possibilita uma sintaxe simples e homogênea na programação da GUI caso seu programa utilize alguma interface com o usuário

DAO - CRUD - ABAP

DAO – CRUD – ABAP

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 Pattern 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.

Criando um programa ABAP

1 – Crie uma tabela transparente chamada ZFUNCIONARIOS utilizando os elementos de dados e as referencias necessárias aos campos CURR do dicionário de dados ABAP:

Tabela transparente - ZFUNCIONARIOS

Tabela transparente – ZFUNCIONARIOS

2 – Crie um menu e um titulo para o Status 100 com as funções necessárias para os eventos dos botões em seu programa e utilize a imagem abaixo para referencia:

Menu Painter

Menu Painter

3 – Crie uma tela de numero 100 no Screen Painter para seu programa com o seguinte layout:

Screen Painter

Screen Painter

 

Exemplo:

Neste exemplo usamos o Pattern DAO para criar operações CRUD utilizando uma interface gráfica. O DAO torna o código ABAP  mais legível pois separa as classes em objetos distintos e proporciona aos desenvolvedores a utilização de uma sintaxe mais homogênea em seus programas.

O exemplo separa o programa principal do objeto de negocio e do objeto de acesso a dados entretanto colocamos as duas classes DAO em um único include, você pode utiliza-las do modo que achar melhor, como por exemplo utilizando-as como classes globais.

ABAP

GUI – ZDAAPP

*&//---------------------------------------------------------------------*
*&// Report  ZDAAPP
*&//
*&//---------------------------------------------------------------------*
*&// Desenvolvimento Aberto
*&// DAO - DAAPP
*&//---------------------------------------------------------------------*

REPORT  ZDAAPP.

*// Chama include
*// ZFUNCIONARIO é a classe de negocio
*//              você pode incluir qualquer regra
*//              para validação em seus métodos.
*//
*// ZFUNCIONARIODAO é a classe de acesso a dados
*//                 utiliza o OPEN SQL como o
*//                 Pattern Factory Method já
*//                 que ele faz um trabalho equivalente

INCLUDE ZFUNCIONARIO.

*// Define objetos e variáveis
DATA : funcionario     TYPE REF TO ZFUNCIONARIO,
       funcionarioDAO  TYPE REF TO ZFUNCIONARIODAO,
       resultado       TYPE ABAP_BOOL,
       TPESQUISAR      TYPE string,
       TID             TYPE string,
       tnome           TYPE string,
       tsobre          TYPE string,
       tcargo          TYPE string,
       tsalario        TYPE string,
       cid             TYPE i,
       csal            TYPE ZSAL.

START-OF-SELECTION.

*// Cria objetos
  CREATE OBJECT FUNCIONARIO.
  CREATE OBJECT FUNCIONARIODAO.

*// Define eventos clique para os botões
  DATA : OK_CODE    LIKE   SY-UCOMM,
         clique_ok  LIKE   sy-ucomm.

*// chama tela numero 100
  CALL SCREEN 100.

*// Modulo PBO
MODULE STATUS_0100 OUTPUT.

*// Define Menu e titulo do programa
  SET PF-STATUS '100'.
  SET TITLEBAR 'ZDAAPPT'.

*// Limpa evento de clique
 clique_ok = ok_code.
 CLEAR ok_code.

*// verifica ação dos botões
  CASE clique_ok.

    WHEN 'FPESQUISAR'.

      "// Trasferencia de objeto
      FUNCIONARIO = FUNCIONARIODAO->BUSCAFUNCIONARIO( TPESQUISAR ).

      "// Recupera valores e alimenta GUI
      tid = FUNCIONARIO->GETID( ).
      tnome = FUNCIONARIO->GETNOME( ).
      tsobre = FUNCIONARIO->GETSOBRENOME( ).
      tcargo = FUNCIONARIO->GETCARGO( ).
      tsalario = FUNCIONARIO->GETSALARIO( ).

    WHEN 'FNOVO'.

      " Limpa GUI
      clear:
      tid,
      tnome,
      tsobre,
      tcargo,
      tsalario.

    WHEN 'FINSERIR'.

      "// Converte valores para o objeto
      cid = tid.
      csal = tsalario.

      "// Adicona valores ao objeto
      FUNCIONARIO->SETID( cid  ).
      FUNCIONARIO->SETNOME( tnome ).
      FUNCIONARIO->SETSOBRENOME( tsobre ).
      FUNCIONARIO->SETCARGO( tcargo ).
      FUNCIONARIO->SETSALARIO( csal ).

      "// Insere dados no banco
      RESULTADO = FUNCIONARIODAO->INSERIRFUNCIONARIO( FUNCIONARIO ).

      "// Verifica resultados
      IF ( RESULTADO EQ ABAP_TRUE ).
        MESSAGE 'Dados inseridos com sucesso' TYPE 'S'.
      ELSE.
        MESSAGE 'Erro ao inserir dados' TYPE 'E'.
      ENDIF.

*// Os evento subsequentes utilizam a mesma sintaxe do evento acima
*// criando um metodo simples e facil para gravar dados
*// uma vez que você tenha qualquer objeto de negocio
*// e um objeto de acesso a dados.

      WHEN 'FALTERAR'.

      cid = tid.
      csal = tsalario.

      FUNCIONARIO->SETID( cid  ).
      FUNCIONARIO->SETNOME( tnome ).
      FUNCIONARIO->SETSOBRENOME( tsobre ).
      FUNCIONARIO->SETCARGO( tcargo ).
      FUNCIONARIO->SETSALARIO( csal ).

      RESULTADO = FUNCIONARIODAO->ALTERARFUNCIONARIO( FUNCIONARIO ).
      IF ( RESULTADO EQ ABAP_TRUE ).
        MESSAGE 'Dados alterados com sucesso' TYPE 'S'.
      ELSE.
        MESSAGE 'Erro ao inserir dados' TYPE 'E'.
      ENDIF.

      WHEN 'FAPAGAR'.

      cid = tid.
      csal = tsalario.

      FUNCIONARIO->SETID( cid  ).
      FUNCIONARIO->SETNOME( tnome ).
      FUNCIONARIO->SETSOBRENOME( tsobre ).
      FUNCIONARIO->SETCARGO( tcargo ).
      FUNCIONARIO->SETSALARIO( csal ).

      RESULTADO = FUNCIONARIODAO->APAGARFUNCIONARIO( FUNCIONARIO ).
      IF ( RESULTADO EQ ABAP_TRUE ).
        MESSAGE 'Dados apagados com sucesso' TYPE 'S'.
      ELSE.
        MESSAGE 'Erro ao inserir dados' TYPE 'E'.
      ENDIF.

    WHEN 'FSAIR'.
      LEAVE PROGRAM.

  ENDCASE.
ENDMODULE.

Include – Objeto negocio e Objeto dados

*&//---------------------------------------------------------------------*
*&// Desenvolvimento Aberto - DAO
*&// Objeto de Negocio
*&// Objeto de Dados
*&//
*&// Include           ZFUNCIONARIO
*&//---------------------------------------------------------------------*

*// Cria classe Funcionário
class ZFUNCIONARIO definition.

  public section.

*// Declara construtor com efeito Overload
    methods CONSTRUCTOR IMPORTING
               id        TYPE i      OPTIONAL
               nome      TYPE string OPTIONAL
               sobrenome TYPE string OPTIONAL
               cargo     TYPE string OPTIONAL
               salario   TYPE ZSAL    OPTIONAL.

*// Declara métodos Getter e Setter
*// Você pode incluir algumas validações
*// E criar eventos com um método de retorno para a GUI

    methods SETID importing  !ID type i .
    methods GETID returning value(RESULTADO) type i .

    methods SETNOME importing  !NOME type STRING .
    methods GETNOME returning value(RESULTADO) type STRING .

    methods SETSOBRENOME importing  !SOBRENOME type STRING .
    methods GETSOBRENOME returning value(RESULTADO) type STRING .

    methods SETCARGO importing  !CARGO type STRING .
    methods GETCARGO returning value(RESULTADO) type STRING .

    methods SETSALARIO importing  !SALARIO type ZSAL.
    methods GETSALARIO returning value(RESULTADO) TYPE ZSAL.

*// Declara atributos privados
  private section.

    data ID        type i.
    data NOME      type STRING .
    data SOBRENOME type STRING .
    data CARGO     type STRING.
    data SALARIO   type ZSAL .

ENDCLASS.

*// Implementação da classe
CLASS ZFUNCIONARIO IMPLEMENTATION.

*//  Construtor

  METHOD CONSTRUCTOR.
    me->ID = ID.
    me->NOME = NOME.
    me->SOBRENOME = SOBRENOME.
    me->CARGO = CARGO.
    me->SALARIO = SALARIO.
  ENDMETHOD.

*//  Metodos Getter e Setter

  METHOD GETID.
    RESULTADO = me->ID.
  ENDMETHOD.

  METHOD SETID.
    me->ID = ID.
  ENDMETHOD.

  METHOD GETNOME.
    RESULTADO = me->NOME.
  ENDMETHOD.

  METHOD SETNOME.
    me->NOME = NOME.
  ENDMETHOD.

  METHOD GETSOBRENOME.
    RESULTADO = me->SOBRENOME.
  ENDMETHOD.

  METHOD SETSOBRENOME.
    me->SOBRENOME = SOBRENOME.
  ENDMETHOD.

  METHOD GETCARGO.
    RESULTADO = me->CARGO.
  ENDMETHOD.

  METHOD SETCARGO.
    me->CARGO = CARGO.
  ENDMETHOD.

  METHOD GETSALARIO.
    RESULTADO = me->SALARIO.
  ENDMETHOD.

  METHOD SETSALARIO.
    me->SALARIO = SALARIO.
  ENDMETHOD.

ENDCLASS.

*&//---------------------------------------------------------------------*
*&// Desenvolvimento Aberto
*&// DAO - ZFUNCIONARIO DAO
*&//---------------------------------------------------------------------*

CLASS ZFUNCIONARIODAO DEFINITION.

*// Metodos DAO

  PUBLIC SECTION.

    METHODS BUSCAFUNCIONARIO IMPORTING ID TYPE STRING
                 RETURNING VALUE(FUNC) TYPE REF TO ZFUNCIONARIO.

    METHODS INSERIRFUNCIONARIO IMPORTING FUNCIONARIO TYPE REF TO ZFUNCIONARIO
                 RETURNING VALUE(RESULTADO) TYPE ABAP_BOOL.

    METHODS ALTERARFUNCIONARIO IMPORTING FUNCIONARIO TYPE REF TO ZFUNCIONARIO
                 RETURNING VALUE(RESULTADO) TYPE ABAP_BOOL.

    METHODS APAGARFUNCIONARIO IMPORTING FUNCIONARIO TYPE REF TO ZFUNCIONARIO
                 RETURNING VALUE(RESULTADO) TYPE ABAP_BOOL.

ENDCLASS.

CLASS ZFUNCIONARIODAO IMPLEMENTATION.

  METHOD BUSCAFUNCIONARIO.

    "// Cria tabela interna
    DATA tab TYPE ZFUNCIONARIOS.

    "// Cria objeto
    DATA FUNCIONARIO TYPE REF TO ZFUNCIONARIO.
    CREATE OBJECT FUNCIONARIO.

    "// Seleciona dados
    SELECT * INTO tab FROM ZFUNCIONARIOS WHERE ID = ID.
    ENDSELECT.

    "// Alimenta objeto
    FUNCIONARIO->SETID( tab-ID ).
    FUNCIONARIO->SETNOME( tab-NOME ).
    FUNCIONARIO->SETSOBRENOME( tab-SOBRENOME ).
    FUNCIONARIO->SETCARGO( tab-CARGO ).
    FUNCIONARIO->SETSALARIO( tab-SALARIO ).

    "// Transfere objeto
    FUNC = FUNCIONARIO.

  ENDMETHOD.

  METHOD INSERIRFUNCIONARIO.

    "// Cria tabela
    DATA tab TYPE ZFUNCIONARIOS.

    "// Recupe dados do objeto e insere na tabela
    tab-ID = FUNCIONARIO->GETID( ).
    tab-NOME = FUNCIONARIO->GETNOME( ).
    tab-SOBRENOME = FUNCIONARIO->GETSOBRENOME( ).
    tab-CARGO = FUNCIONARIO->GETCARGO( ).
    tab-SALARIO = FUNCIONARIO->GETSALARIO( ).

    "// Insere dados na tabela transparente
    INSERT INTO ZFUNCIONARIOS VALUES tab.
    IF SY-SUBRC = 0.
      RESULTADO = ABAP_TRUE.
    ELSE.
      RESULTADO = ABAP_FALSE.
    ENDIF.

  ENDMETHOD.

  METHOD ALTERARFUNCIONARIO.

    "// Cria tabela
    DATA tab TYPE ZFUNCIONARIOS.

    "// Recupe dados do objeto e insere na tabela
    tab-ID = FUNCIONARIO->GETID( ).
    tab-NOME = FUNCIONARIO->GETNOME( ).
    tab-SOBRENOME = FUNCIONARIO->GETSOBRENOME( ).
    tab-CARGO = FUNCIONARIO->GETCARGO( ).
    tab-SALARIO = FUNCIONARIO->GETSALARIO( ).

    "// Altera dados na tabela transparente
    UPDATE ZFUNCIONARIOS
       SET NOME = tab-NOME
           SOBRENOME = tab-SOBRENOME
           CARGO = tab-CARGO
           SALARIO = tab-SALARIO
           WHERE ID = tab-ID.
    IF SY-SUBRC = 0.
      RESULTADO = ABAP_TRUE.
    ELSE.
      RESULTADO = ABAP_FALSE.
    ENDIF.

  ENDMETHOD.

  METHOD APAGARFUNCIONARIO.

    "// Cria tabela
    DATA tab TYPE ZFUNCIONARIOS.

    "// Recupera ID do objeto
    tab-ID = FUNCIONARIO->GETID( ).

    "// Deleta dados da tabela transparente
    DELETE FROM ZFUNCIONARIOS
           WHERE ID = tab-ID.
    IF SY-SUBRC = 0.
      RESULTADO = ABAP_TRUE.
    ELSE.
      RESULTADO = ABAP_FALSE.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

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 também é suportado em C++ através das classes de fundação da Microsoft (MFC).

Devido algumas similaridades 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.

C++ - MFC - DAO

C++ – MFC – DAO

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 Pattern 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 utiliza o objeto de transferência para manipular dados.

Neste exemplo não criamos uma classe abstrata utilizando o Pattern Factory Method, 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 - Design

Visual Studio – Design

Utilize a imagem acima para criar um design parecido.

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.

O DAO  pode ser utilizado para varias soluções como no exemplo abaixo para enfatizar sua eficiência utilizamos o DAO em uma interface gráfica escrita com MFC justamente para mostrar a independência do negocio e acesso a dados.

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.

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 – Negócio

Header

#pragma once

class Funcionario
{

private:
	// Atributos
	long id;
	CString nome;
	CString sobrenome;
	CString cargo;
	double  salario;

public:

	// Construtor
	Funcionario();
	~Funcionario();

	// Construtor Overload
	Funcionario(long id, CString nome, CString sobrenome, CString cargo, double salario);

	// Metodos Getter e Setter
	void setId(long id);
	long getId();

	void setNome(CString nome);
	CString getNome();

	void setSobrenome(CString sobrenome);
	CString getSobrenome();

	void setCargo(CString cargo);
	CString getCargo();

	void setSalario(double salario);
	double getSalario();

};

Cpp

#include "stdafx.h"
#include "Funcionario.h"

// Implementação da classe Funcionarios

Funcionario::Funcionario()
{
}

Funcionario::~Funcionario()
{
}

// Construtor Overload
Funcionario::Funcionario(long id, CString nome, CString sobrenome, CString cargo, double salario)
{
	this->id = id;
	this->nome = nome;
	this->sobrenome = sobrenome;
	this->cargo = cargo;
	this->salario = salario;
}

// Getters e Setters
void Funcionario::setId(long id)
{
	this->id = id;
}

long Funcionario::getId()
{
	return this->id;
}

void Funcionario::setNome(CString nome)
{
	this->nome = nome;
}

CString Funcionario::getNome()
{
	return this->nome;
}

void Funcionario::setSobrenome(CString sobrenome)
{
	this->sobrenome = sobrenome;
}

CString Funcionario::getSobrenome()
{
	return this->sobrenome;
}

void Funcionario::setCargo(CString cargo)
{
	this->cargo = cargo;
}

CString Funcionario::getCargo()
{
	return this->cargo;
}

void Funcionario::setSalario(double salario)
{
	this->salario = salario;
}

double Funcionario::getSalario()
{
	return this->salario;
}

Factory Pattern – DAConexaoFactory

Header

#pragma once

// Inclui classe de banco de dados MFC
#include "afxdb.h"

class DAConexaoFactory
{
private:

	// Define constantes para fonte de dados
	const int ORACLE = 1;
	const int DB2 = 2;
	const int MSSQL = 3;

	// Define dados do usuario
	CString dns, usuario, senha;

	// Define banco de dados

public:

	DAConexaoFactory();
	~DAConexaoFactory();

	CString getConexao(int banco);
};

Cpp

#include "stdafx.h"
#include "DAConexaoFactory.h"

DAConexaoFactory::DAConexaoFactory()
{
}

DAConexaoFactory::~DAConexaoFactory()
{
}

CString DAConexaoFactory::getConexao(int banco)
{

	// Define banco de dados
	if (banco == ORACLE)
	{
		dns = L"OracleXE";
		usuario = L"user";
		senha = L"pass";
	}

	if (banco == DB2)
	{
		dns = L"IBMDB2";
		usuario = L"user";
		senha = L"pass";
	}

	if (banco == MSSQL)
	{
		dns = L"MSSQLSERVER";
		usuario = L"user";
		senha = L"pass";
	}

	// Cria string de conexão ODBC
	CString conexao;

	// Cria string de conexão
	conexao = L"DSN=" + dns + L";UID=" + usuario + L";PWD=" + senha;

	// Abre conexão

	return  conexao;
}

Objeto DAO – FuncionarioDAO

Header

#pragma once

#include "afxdb.h"
#include "IDaoFuncionario.h"

class FuncionarioDAO
{

private:
	// Define objetos
	CDatabase conn;
	CString erro;
	TCHAR menssagem[255];

public:	

	FuncionarioDAO();
	~FuncionarioDAO();

	// Metodos DAO

	Funcionario buscaFuncionario(CString id);

	bool insereFuncionario(Funcionario& funcionario);

	bool alterarFuncionario(Funcionario& funcionario);

	bool deletarFuncionario(Funcionario& funcionario);

	CString getErro();

};

Cpp

#include "stdafx.h"
#include "FuncionarioDAO.h"
#include "DAConexaoFactory.h"

FuncionarioDAO::FuncionarioDAO()
{
	DAConexaoFactory conexao = DAConexaoFactory();
	conn.OpenEx(conexao.getConexao(1), 0);

}

FuncionarioDAO::~FuncionarioDAO()
{
}

Funcionario FuncionarioDAO::buscaFuncionario(CString id)
{
	// Cria objeto de negocio
	Funcionario funcionario = Funcionario();
	CString m_conteudo;

	try
	{
		// Define Set de dados
		CRecordset dados(&conn);

		// Executa SQL
		dados.Open(CRecordset::forwardOnly,
			L"Select * From Funcionarios Where  ID_FUNCIONARIO = " + id);

		// carrega dados no objeto
		dados.GetFieldValue(L"ID_FUNCIONARIO", m_conteudo);
		funcionario.setId(_wtoi(m_conteudo));
		dados.GetFieldValue(L"NOME", m_conteudo);
		funcionario.setNome(m_conteudo);
		dados.GetFieldValue(L"SOBRENOME", m_conteudo);
		funcionario.setSobrenome(m_conteudo);
		dados.GetFieldValue(L"CARGO", m_conteudo);
		funcionario.setCargo(m_conteudo);
		dados.GetFieldValue(L"SALARIO", m_conteudo);
		m_conteudo.Replace(_T(","), _T("."));
		funcionario.setSalario(_wtof(m_conteudo));

		dados.Close();
	}
	catch (CDBException* ex )
	{
		// Define erro
		ex->GetErrorMessage(menssagem, 255);
	    erro += menssagem ;
	}

	// Retorna objeto
	return funcionario;
}

bool FuncionarioDAO::insereFuncionario(Funcionario& funcionario)
{
	// Define variaveis
	CString m_id;
	CString m_salario;

	// Formata valores
	long id = funcionario.getId();
	m_id.Format(_T("%ld"), id);

	double salario = funcionario.getSalario();
    m_salario.Format(_T("%g"), salario);

	// Cria instrução SQL
	CString sql = L"Insert into  Funcionarios  values ( " + m_id + ", " +
		"'" + funcionario.getNome() + "', " +
		"'" + funcionario.getSobrenome() + "', " +
		"'" + funcionario.getCargo() + "', " +
		m_salario + ")";

	try
	{
		// Executa SQL
		conn.ExecuteSQL(sql);
		return true;
	}
	catch (CDBException* ex)
	{
		// Define erro
		ex->GetErrorMessage(menssagem, 255);
		erro += menssagem;
		return false;
	}

}

bool FuncionarioDAO::alterarFuncionario(Funcionario& funcionario)
{
	// Define variaveis
	CString m_id;
	CString m_salario;

	// Define valores
	long id = funcionario.getId();
	m_id.Format(_T("%ld"), id);

	double salario = funcionario.getSalario();
	m_salario.Format(_T("%g"), salario);

	// Cria instrução SQL
	CString sql = L"Update  Funcionarios  set ID_FUNCIONARIO = " + m_id + ", " +
		" NOME= '" + funcionario.getNome() + "', " +
		" SOBRENOME= '" + funcionario.getSobrenome() + "', " +
		" CARGO = '" + funcionario.getCargo() +
		" ', SALARIO = " + 	m_salario +
		" WHERE ID_FUNCIONARIO = " + m_id ;

	try
	{
		// Executa SQL
		conn.ExecuteSQL(sql);
		return true;
	}
	catch (CDBException* ex)
	{
		// Define erro
		ex->GetErrorMessage(menssagem, 255);
		erro += menssagem;
		return false;
	}

}

bool FuncionarioDAO::deletarFuncionario(Funcionario& funcionario)
{
	// Define variaveis
	CString m_id;

	// Define valores
	long id = funcionario.getId();
	m_id.Format(_T("%ld"), id);

	// Cria instrução SQL
	CString sql = L"Delete from  Funcionarios WHERE ID_FUNCIONARIO = " + m_id;

	try
	{
		// Executa SQL
		conn.ExecuteSQL(sql);
		return true;
	}
	catch (CDBException* ex)
	{
		// Define Erro
		ex->GetErrorMessage(menssagem, 255);
		erro += menssagem;
		return false;
	}
}

CString FuncionarioDAO::getErro()
{
	// Retorna Erro
	return erro;
}

GUI – DADaoApp

Header


// CamposcppDlg.h : header file
//

#pragma once

#include "afxwin.h"

// CCamposcppDlg dialog
class CCamposcppDlg : public CDialogEx
{

public:
	CCamposcppDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	enum { IDD = IDD_CAMPOSCPP_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support

// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

public:

	// Variaveis Edits
	CEdit m_pesquisa;
	CEdit m_codigo;
	CEdit m_pnome;
	CEdit m_snome;
	CEdit m_cargo;
	CEdit m_salario;

	// Variaveis Botões
	CButton m_apagar;
	CButton m_novo;

	// Eventos
	afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
	afx_msg void OnBnClickedButton1();
	afx_msg void OnBnClickedButton2();
	afx_msg void OnBnClickedButton3();
	afx_msg void OnBnClickedButton4();
	afx_msg void OnBnClickedButton5();

private:

	// Campos
	CString codigo;
	CString pnome;
	CString snome;
	CString cargo;
	CString salario;

};

Cpp


// CamposcppDlg.cpp : implementation file
//

#include "stdafx.h"
#include "afxwin.h"
#include "Camposcpp.h"
#include "CamposcppDlg.h"
#include "afxdialogex.h"
#include "Funcionario.h"
#include "FuncionarioDAO.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CCamposcppDlg::CCamposcppDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CCamposcppDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCamposcppDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT6, m_pesquisa);
	DDX_Control(pDX, IDC_EDIT1, m_codigo);
	DDX_Control(pDX, IDC_EDIT2, m_pnome);
	DDX_Control(pDX, IDC_EDIT3, m_snome);
	DDX_Control(pDX, IDC_EDIT4, m_cargo);
	DDX_Control(pDX, IDC_EDIT5, m_salario);
	DDX_Control(pDX, IDC_BUTTON5, m_apagar);
	DDX_Control(pDX, IDC_BUTTON2, m_novo);

}

BEGIN_MESSAGE_MAP(CCamposcppDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CCamposcppDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CCamposcppDlg::OnBnClickedButton2)

ON_WM_SHOWWINDOW()
ON_BN_CLICKED(IDC_BUTTON3, &CCamposcppDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CCamposcppDlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &CCamposcppDlg::OnBnClickedButton5)
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()

BOOL CCamposcppDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);
	return TRUE;
}

void CCamposcppDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); 

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

HCURSOR CCamposcppDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

// ************************         Desenvolvimento Aberto
// Nosso código começa aqui

void CCamposcppDlg::OnBnClickedButton1()
{
	// Referincia objeto statico
	CWnd * p_rotulo;

	// Associa objeto statico
	p_rotulo = GetDlgItem(IDC_Rotulo);
	p_rotulo->SetWindowTextW(L"DAO - Pattern");

	// Define variaveis
	CString codigo;

	// Cria objetos DAO
	Funcionario funcionario = Funcionario();
	FuncionarioDAO pesquisar = FuncionarioDAO();

	// Cria pesquisa
	m_pesquisa.GetWindowTextW(codigo);

	// Busca objeto
	funcionario = pesquisar.buscaFuncionario(codigo);

	// recupera dados do objeto e transfere para a GUI
	CString m_conteudo;
	long m_id = funcionario.getId();
	m_conteudo.Format(_T("%ld"), m_id);

	m_codigo.SetWindowTextW(m_conteudo);
	m_pnome.SetWindowTextW(funcionario.getNome());
	m_snome.SetWindowTextW(funcionario.getSobrenome());
	m_cargo.SetWindowTextW(funcionario.getCargo());

	double m_sal = funcionario.getSalario();
	m_conteudo.Format(_T("%g"), m_sal);
	m_salario.SetWindowTextW(m_conteudo);
}

void CCamposcppDlg::OnBnClickedButton2()
{
	// Limpa componentes
	m_codigo.SetWindowTextW(NULL);
	m_pnome.SetWindowTextW(NULL);
	m_snome.SetWindowTextW(NULL);
	m_cargo.SetWindowTextW(NULL);
	m_salario.SetWindowTextW(NULL);

	// Define foco
	CEdit* pesquisa;
	pesquisa = (CEdit*)GetDlgItem(IDC_EDIT1);
	GotoDlgCtrl(pesquisa);
}

void CCamposcppDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CDialogEx::OnShowWindow(bShow, nStatus);

	// Define foco inicial
	CEdit* pesquisa;
	pesquisa = (CEdit*)GetDlgItem(IDC_EDIT6);
	GotoDlgCtrl(pesquisa);
}

// Clique do botão inserir
void CCamposcppDlg::OnBnClickedButton3()
{
	// Recupara texto dos componentes
	m_codigo.GetWindowTextW(codigo);
	m_pnome.GetWindowTextW(pnome);
	m_snome.GetWindowTextW(snome);
	m_cargo.GetWindowTextW(cargo);
	m_salario.GetWindowTextW(salario);

	// Troca ponto decimal para o banco de dados
	int i = salario.Replace(L",", L".");

	// Cria objetos DAO
	Funcionario funcionario = Funcionario();
	FuncionarioDAO inserir = FuncionarioDAO();

	// Alimenta dados ao objeto
	funcionario.setId(_wtoi(codigo));
	funcionario.setNome(pnome);
	funcionario.setSobrenome(snome);
	funcionario.setCargo(cargo);
	funcionario.setSalario(_wtof(salario));

	// Verifica resultado
	bool resultado = inserir.insereFuncionario(funcionario);

	if (resultado)
	{
		AfxMessageBox(L"Dados inseridos com sucesso!");
	}
	else
	{
		AfxMessageBox(inserir.getErro());
	}	

}

// botão Updata
void CCamposcppDlg::OnBnClickedButton4()
{
	// Recupara texto dos componentes
	m_codigo.GetWindowTextW(codigo);
	m_pnome.GetWindowTextW(pnome);
	m_snome.GetWindowTextW(snome);
	m_cargo.GetWindowTextW(cargo);
	m_salario.GetWindowTextW(salario);

	// Troca ponto decimal para o banco de dados
	int i = salario.Replace(L",", L".");

	// Cria objetos DAO
	Funcionario funcionario = Funcionario();
	FuncionarioDAO alterar = FuncionarioDAO();

	// Alimenta dados no objeto
	funcionario.setId(_wtoi(codigo));
	funcionario.setNome(pnome);
	funcionario.setSobrenome(snome);
	funcionario.setCargo(cargo);
	funcionario.setSalario(_wtof(salario));

	// Altera objeto
	bool resultado = alterar.alterarFuncionario(funcionario);

	// Verifica resultado
	if (resultado)
	{
		AfxMessageBox(L"Dados alterados com sucesso!");
	}
	else
	{
		AfxMessageBox(alterar.getErro());
	}
}

void CCamposcppDlg::OnBnClickedButton5()
{
	// Recupera dados da GUI
	m_codigo.GetWindowTextW(codigo);
	m_pnome.GetWindowTextW(pnome);
	m_snome.GetWindowTextW(snome);
	m_cargo.GetWindowTextW(cargo);
	m_salario.GetWindowTextW(salario);

	// Troca ponto decimal para o banco de dados
	int i = salario.Replace(L",", L".");

	// Cria objetos DAO
	Funcionario funcionario = Funcionario();
	FuncionarioDAO apagar = FuncionarioDAO();

	// Alimenta dados ao objeto
	funcionario.setId(_wtoi(codigo));
	funcionario.setNome(pnome);
	funcionario.setSobrenome(snome);
	funcionario.setCargo(cargo);
	funcionario.setSalario(_wtof(salario));

	// Apaga objeto
	bool resultado = apagar.deletarFuncionario(funcionario);

	// Verifica resultado
	if (resultado)
	{
		AfxMessageBox(L"Dados apagados com sucesso!");
	}
	else
	{
		AfxMessageBox(apagar.getErro());
	}
}

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.

DAO e Python

O DAO é um Pattern da Oracle J2EE para Java, entretanto se tornou um padrão muito popular na programação orientada a objeto, pois separa a logica de negocio da logica do banco de dados e consequentemente da interface com o usuário. Apesar das diferenças entre a linguagem orientada a objeto Java e Python o DAO pode ser usado sem problemas com algumas variações e sendo um padrão flexível e intuitivo é bem possível que você já o utilize nos seus códigos orientados a objeto.

DAO - CRUD - Python

DAO – CRUD – Python

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 Pattern 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 (Python não possui interfaces)  você pode criar as classes DAO como, DAOFuncionarioOracle, DAOFuncionarioDB2 e utiliza o objeto de transferência para manipular dados.

Neste exemplo não criamos uma classe abstrata utilizando o Pattern Factory Method, 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.

DAO - Python Packages

DAO – Python Packages

Utilize a imagem acima para ver a organização das Packges para cada classe e atente-se aos 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 DAConexaoFactory.

O DAO  pode ser utilizado para varias soluções como no exemplo abaixo para enfatizar sua eficiência utilizamos o DAO em uma interface gráfica escrita com Tkinter justamente para mostrar a independência do negocio e acesso a dados.

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.

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));

Python

Objeto – Negócio

# coding=utf-8
# Desenvolvimento Aberto
# Funcionario.py

__author__ = 'Desenvolvimento Aberto'

class Funcionario():

    # Define atributos privados
    def __init__(self):
        self.__id = None
        self.__nome = None
        self.__sobrenome = None
        self.__cargo = None
        self.__salario = None

    # Define métodos Getter e Setter
    # Você também pode optar por propriedades
    def getId(self):
        return self.__id

    def setId(self, id):
        self.__id = id

    def getNome(self):
        return self.__nome

    def setNome(self, nome):
        self.__nome = nome

    def getSobrenome(self):
        return self.__sobrenome

    def setSobrenome(self, sobrenome):
        self.__sobrenome = sobrenome

    def getCargo(self):
        return self.__cargo

    def setCargo(self, cargo):
        self.__cargo = cargo

    def getSalario(self):
        return self.__salario

    def setSalario(self, salario):
        self.__salario = salario

Factory Pattern – DAConexaoFactory

# coding=utf-8
# Desenvolvimento Aberto
# DAConexaoFactory.py

__author__ = 'Desenvolvimento Aberto'

# Importa fonte de dados
import cx_Oracle
import ibm_db
import odbc

class DAConexaoFactory():

    # Define atributos privados

    def __init__(self):
        self.__ORACLE = 1
        self.__DB2 = 2
        self.__MSSQL = 3
        self.__erroCon = None
        self.__factory = None
        self.__IBMDriver = None # IBM DB2 driver (ibm_db)

    # Cria Factory para objetos
    def getConexao(self, banco):

        # Define conexão e fonte de dados
        con = None
        self.__factory = banco

        # Cria string de conexão Oracle
        if (banco == self.__ORACLE):
            sconexao = "user/pass@localhost/XE"
            try:
                con = cx_Oracle.connect(sconexao)
            except Exception, e:
                self.__erroCon = str(e)

        # Cria string de conexão IBM DB2
        if (banco == self.__DB2):
            sconexao = "DATABASE=DEVA" + \
                       ";HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;" + \
                       "UID=user;" + \
                       "PWD=pass"
            try:
                self.__IBMDriver = ibm_db
                con = ibm_db.connect(sconexao, "", "")
            except Exception, e:
                self.__erroCon = str(e)

        # Cria string de conexão MSSQL
        if (banco == self.__MSSQL):
            sconexao = "MSSQLSERVER/user/pass"
            try:
                con = odbc.odbc(sconexao)
            except Exception, e:
                self.__erroCon = str(e)

        return con

    # Retorna Erros
    def getErros(self):
        return self.__erroCon

    # Retorna Factory da conexão
    def getFactory(self):
        return self.__factory

    # Retorna Driver da IBM (Oracle e MSSQL possui outro padrão)
    def getIbmDriver(self):
        return self.__IBMDriver

Objeto DAO – FuncionarioDAO

# coding=utf-8
# Desenvolvimento Aberto
# FuncionarioDAO.py

__author__ = 'Desenvolvimento Aberto'

# Importa pacotes DAO
from DesenvolvimentoAberto.Modelo.Funcionario import Funcionario
from DesenvolvimentoAberto.Conexao.DAConexaoFactory import DAConexaoFactory

class FuncionarioDAO():

    # Construtor da classe
    def __init__(self):
        self.__erro = None
        self.__con = None
        self.__factory = None
        self.__IBMDriver = None
        try:
            # Cria Conexão com o Factory Method Pattern
            # Você pode ter uma classe para cada fonte de dados
            # Unimos as três fontes para o exemplo
            conexao = DAConexaoFactory()
            self.__con = conexao.getConexao(3)
            self.__factory = conexao.getFactory()
            self.__IBMDriver = conexao.getIbmDriver()
        except Exception, e:
            self.__erro = str(e)

    # Metodo de Manipulação de dados

    def buscaFuncionario(self, id):

        # Cria instancia do objeto
        funcionario = Funcionario()

        # Define SQL
        sql = "SELECT * FROM FUNCIONARIOS WHERE ID_FUNCIONARIO = " + str(id)

        # Executa SQL
        try:
            if (self.__factory != 2):
                cursor= self.__con.cursor()
                cursor.execute(sql)
                dados = cursor.fetchone()

            else:
                cursor = self.__IBMDriver.exec_immediate(self.__con, sql)
                dados  = self.__IBMDriver.fetch_tuple(cursor)

        except Exception, e:
            self.__erro = str(e)

        # Alimenta objeto
        funcionario.setId(dados[0])
        funcionario.setNome(dados[1])
        funcionario.setSobrenome(dados[2])
        funcionario.setCargo(dados[3])
        funcionario.setSalario(dados[4])

        # Retorna Objeto
        return funcionario

    def insereFuncionario(self, funcionario ):

        # Define SQL
        # Troca decimal é requerido se Oracle/DB2 for ptbr.
        sql = "INSERT INTO FUNCIONARIOS VALUES (" + \
              funcionario.getId() + ", '" + \
              funcionario.getNome() + "', '" + \
              funcionario.getSobrenome() + "', '" + \
              funcionario.getCargo() + "', " + \
              str(funcionario.getSalario()).replace(",",".") + ")"

        # Executa SQL
        try:
             if (self.__factory != 2):
                 cursor=self.__con.cursor()
                 cursor.execute(sql)
                 self.__con.commit()
                 return True
             else:
                 cursor = self.__IBMDriver.exec_immediate(self.__con, sql)
                 return True

        except Exception, e:
            self.__erro = str(e)
            return False

    def alteraFuncionario(self, funcionario):

       #  Define SQL
       sql = "UPDATE FUNCIONARIOS SET " + \
             "ID_FUNCIONARIO = " + funcionario.getId() + ", " + \
             "NOME = '" + funcionario.getNome() + "', " + \
             "SOBRENOME = '" + funcionario.getSobrenome() + "', " + \
             "CARGO = '" + funcionario.getCargo() + "', " + \
             "SALARIO = " + str(funcionario.getSalario()).replace(",",".") + \
             " WHERE ID_FUNCIONARIO = " + funcionario.getId()

       # Executa SQL
       try:
           if (self.__factory != 2):
               cursor=self.__con.cursor()
               cursor.execute(sql)
               self.__con.commit()
               return True
           else:
               cursor = self.__IBMDriver.exec_immediate(self.__con, sql)
               return True

       except Exception, e:
           self.__erro = str(e)
           return False

    def apagarFuncionario(self, funcionario):

        # Define SQL
        sql = "DELETE FROM FUNCIONARIOS WHERE ID_FUNCIONARIO = " + funcionario.getId()

        # Executa SQL
        try:
            if (self.__factory != 2):
                cursor=self.__con.cursor()
                cursor.execute(sql)
                self.__con.commit()
                return True
            else:
                cursor = self.__IBMDriver.exec_immediate(self.__con, sql)
                return True

        except Exception, e:
            self.__erro = str(e)
            return False

    # Retorna Erro
    def getErro(self):
        return self.__erro

GUI – DADaoApp

#!/usr/bin/env python
# coding=utf-8
# Desenvolvimento Aberto
# DADaoApp.py

# importa modulos
from Tkinter import *
from DesenvolvimentoAberto.Modelo.Funcionario import Funcionario
from DesenvolvimentoAberto.Dao.FuncionarioDAO import FuncionarioDAO
import tkMessageBox

class DADaoApp(Frame):

    def __init__(self, formulario=None):

        # Define formulario
        Frame.__init__(self, formulario)

        # Cria Widgets
        self.titulo = Label(formulario, text="DAO - Pattern")
        self.separador1 = Frame(height=2, bd=1, relief=SUNKEN)
        self.separador2 = Frame(height=2, bd=1, relief=SUNKEN)

        # labels
        self.lcodigo = Label(formulario, text="Codigo:")
        self.lpnome = Label(formulario, text="Nome:")
        self.lsnome = Label(formulario, text="Sobrenome:")
        self.lcargo = Label(formulario, text="Cargo:")
        self.lsalario = Label(formulario, text="Salario:")

        # Entry
        self.tcodigo = Entry(formulario, width=20)
        self.tpnome = Entry(formulario, width=50)
        self.tsnome = Entry(formulario, width=45)
        self.tcargo = Entry(formulario, width=35)
        self.tsalario = Entry(formulario, width=30)

        # Pesquisa
        self.lpesquisa = Label(formulario, text="Pesquisa:")
        self.tpesquisa = Entry(formulario)
        self.botao = Button(formulario, text="Pesquisar", command=self.on_Pesquisar)

        # Ações
        self.painel = Frame()
        self.bnovo = Button(self.painel, text="Novo", command=self.on_novo, width=8)
        self.binserir = Button(self.painel, text="Inserir", command=self.on_inserir, width=8)
        self.balterar = Button(self.painel, text="Alterar", command=self.on_alterar, width=8)
        self.bapagar = Button(self.painel, text="Apagar", command=self.on_apagar, width=8)

        # Cria janela para menssagem
        self.janela = Tk()
        self.janela.wm_withdraw()

        # Define Layout
        self.titulo.grid(row=0, sticky=W+E+N+S, pady=20)
        self.separador1.grid(row=1, sticky=W+E+N+S, columnspan=3)

        # Define Layout Dados
        self.lcodigo.grid(row=3, sticky=W, padx=20)
        self.tcodigo.grid(row=3, column=1, pady=5, sticky=W)
        self.lpnome.grid(row=4, sticky=W, padx=20)
        self.tpnome.grid(row=4, column=1, pady=5, sticky=W)
        self.lsnome.grid(row=5, sticky=W, padx=20)
        self.tsnome.grid(row=5, column=1, pady=5, sticky=W)
        self.lcargo.grid(row=6, sticky=W, padx=20)
        self.tcargo.grid(row=6, column=1, pady=5, sticky=W)
        self.lsalario.grid(row=7, sticky=W, padx=20)
        self.tsalario.grid(row=7, column=1, pady=5, sticky=W)

        # Layout pesquisa
        self.lpesquisa.grid(row=2, column=0, pady=20)
        self.tpesquisa.grid(row=2, column=1, pady=20)
        self.botao.grid(row=2, column=2, padx=10, pady=20)

        # Loayout Ações
        self.bnovo.grid(row=1, column=0, pady=10, padx=5)
        self.binserir.grid(row=1, column=1, pady=10, padx=5)
        self.balterar.grid(row=1, column=2, pady=10, padx=5)
        self.bapagar.grid(row=1, column=3, pady=10, padx=5)
        self.separador2.grid(row=9, sticky=W+E, columnspan=3, pady=10)
        self.painel.grid(row=10, sticky=W+E+S, column=1, columnspan=1)

    # Limpa campo
    def limpar(self):
        self.tcodigo.delete(0, END)
        self.tpnome.delete(0, END)
        self.tsnome.delete(0, END)
        self.tcargo.delete(0, END)
        self.tsalario.delete(0, END)

    # Evento do botão
    def on_Pesquisar(self):

        # Cria objetos Modelo e DAO
        funcionario = Funcionario()
        pesquisar = FuncionarioDAO()

        # Executa trasferencia de Objetos
        try:
            funcionario = pesquisar.buscaFuncionario(self.tpesquisa.get())
        except ValueError:
            tkMessageBox.showinfo(title="Erro", message=pesquisar.getErro(), parent=self.janela)

        # Exibe dados
        self.limpar()
        self.tcodigo.insert(0, str(funcionario.getId()))
        self.tpnome.insert(0, funcionario.getNome())
        self.tsnome.insert(0, funcionario.getSobrenome())
        self.tcargo.insert(0, funcionario.getCargo())
        self.tsalario.insert(0, str(funcionario.getSalario()))

    # limpa widgets
    def on_novo(self):
        self.limpar()
        self.tcodigo.focus()

    # Insere dados
    def on_inserir(self):

        # Cria objeto Modelo
        funcionario = Funcionario()

        # Alimenta dados ao objeto
        funcionario.setId(self.tcodigo.get())
        funcionario.setNome(self.tpnome.get())
        funcionario.setSobrenome(self.tsnome.get())
        funcionario.setCargo(self.tcargo.get())
        funcionario.setSalario(self.tsalario.get())

        # Cria objeto DAO
        inserir = FuncionarioDAO()

        # Executa trasferencia de Objetos
        resultado = inserir.insereFuncionario(funcionario)

        # Exibe Resultado
        if (resultado):
            tkMessageBox.showinfo(title="Menssagem", message="Dados inseridos com suscesso!", parent=self.janela)
        else:
            tkMessageBox.showinfo(title="Erro", message=inserir.getErro(), parent=self.janela)

    # Altera dados
    def on_alterar(self):
        # Cria objeto Modelo
        funcionario = Funcionario()

        # Alimenta objeto
        funcionario.setId(self.tcodigo.get())
        funcionario.setNome(self.tpnome.get())
        funcionario.setSobrenome(self.tsnome.get())
        funcionario.setCargo(self.tcargo.get())
        funcionario.setSalario(self.tsalario.get())

        # Cria objeto DAO
        alterar = FuncionarioDAO()

        # # Executa trasferencia de Objetos
        resultado = alterar.alteraFuncionario(funcionario)

        # Exibe resultado
        if (resultado):
            tkMessageBox.showinfo(title="Menssagem", message="Dados alterados com suscesso!", parent=self.janela)
        else:
            tkMessageBox.showinfo(title="Erro", message=alterar.getErro(), parent=self.janela)

    # Exclui dados
    def on_apagar(self):

        # Cria objeto Modelo
        funcionario = Funcionario()

        # Alimenta objeto
        funcionario.setId(self.tcodigo.get())
        funcionario.setNome(self.tpnome.get())
        funcionario.setSobrenome(self.tsnome.get())
        funcionario.setCargo(self.tcargo.get())
        funcionario.setSalario(self.tsalario.get())

        #Cria objeto DAO
        apagar = FuncionarioDAO()

        # Executa trasferencia de Objetos
        resultado = apagar.apagarFuncionario(funcionario)

        # Exibe resultado
        if (resultado):
            tkMessageBox.showinfo(title="Menssagem", message="Dados apagados com suscesso!", parent=self.janela)
            self.limpar()
        else:
            tkMessageBox.showinfo(title="Erro", message=apagar.getErro(), parent=self.janela)

# loop do tcl
root = Tk()
root.title('DA - DAO - Data Access Object')
app = DADaoApp(formulario=root)
app.mainloop()
root.destroy()

 

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());
            }
        }
    }
}

 

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.

CRUD - DAO

CRUD – DAO

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 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.

Eclipse IDE - Drivers - Oracle - DB2 - MSSQL

Eclipse IDE – Drivers – Oracle – DB2 – MSSQL

Utilize a imagem acima para ver a organização das Packges 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 JPA 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));

Java

JavaBean – Funcionario

package org.desenvolvimento.aberto.modelo;

// Modelos utilizam JavaBean
public class Funcionario {

	// Declara atributos
	private long Id;
	private String nome;
	private String sobrenome;
	private String cargo;
	private double salario;

	// Método construtor padrão do JavaBean
	public Funcionario() {

	}

	// Método 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 métodos Getters e Setters
	public long getId() {
		return Id;
	}

	public void setId(long id) {
		Id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getSobrenome() {
		return sobrenome;
	}

	public void setSobrenome(String sobrenome) {
		this.sobrenome = sobrenome;
	}

	public String getCargo() {
		return cargo;
	}

	public void setCargo(String cargo) {
		this.cargo = cargo;
	}

	public double getSalario() {
		return salario;
	}

	public void setSalario(double salario) {
		this.salario = salario;
	}

}

Factory Pattern – DAConexaoFactory

package org.desenvolvimento.aberto.conexao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DAConexaoFactory {

	// Cria string de conexão de banco de dados
	private static String conexao;

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

	public static Connection getConexao(int fabrica, String usuario,
			String senha) throws ClassNotFoundException, SQLException {

		if (fabrica == 1) {
			conexao = "jdbc:oracle:thin:@localhost:1521:xe";
			Class.forName("oracle.jdbc.driver.OracleDriver");
		}

		if (fabrica == 2) {
			conexao = "jdbc:derby:net://localhost:50000/deva";
			Class.forName("com.ibm.db2.jcc.DB2Driver");
		}

		if (fabrica == 3) {
			conexao = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=devaberto";
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
		}

		// Retorna driver pronto para login
		return DriverManager.getConnection(conexao, usuario, senha);

	}

}

Interface – FuncionarioDAOInterface

package org.desenvolvimento.aberto.dao;

import org.desenvolvimento.aberto.modelo.Funcionario;

public interface FuncionarioDAOInterface {

	// Cria interface
	// A interface propricia os retornos corretos de cada operação.

	public Funcionario buscaFuncionario(String id);

	public boolean insereFuncionario(Funcionario funcionario);

	public boolean updateFuncionario(Funcionario funcionario);

	public boolean deletaFuncionario(Funcionario funcionario);

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

Objeto DAO – FuncionarioDAO

package org.desenvolvimento.aberto.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.desenvolvimento.aberto.conexao.DAConexaoFactory;
import org.desenvolvimento.aberto.modelo.Funcionario;

public class FuncionarioDAO implements FuncionarioDAOInterface {

	// Cria componentes
	private Connection conn = null;
	private Statement query;
	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 = DAConexaoFactory
					.getConexao(1, "user", "password");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public Funcionario buscaFuncionario(String id) {

		// Cria novo objeto
		Funcionario funcionario = new Funcionario();

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

		try {

			// Associa conexão e executa SQL
			query = conn.createStatement();
			ResultSet rs = query.executeQuery(sql);

			// Recupera dados do set
			while (rs.next()) {
				funcionario.setId(rs.getInt("ID_FUNCIONARIO"));
				funcionario.setNome(rs.getString("NOME"));
				funcionario.setSobrenome(rs.getString("SOBRENOME"));
				funcionario.setCargo(rs.getString("CARGO"));
				funcionario.setSalario(rs.getDouble("SALARIO"));
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Retorna objeto
		return funcionario;
	}

	@Override
	public boolean insereFuncionario(Funcionario funcionario) {

		// Define SQL
		sql = "INSERT INTO FUNCIONARIOS VALUES (?, ?, ?, ?, ?)";

		try {

			// Prepara SQL e alimenta parametros
			PreparedStatement query = conn.prepareStatement(sql);
			query.setLong(1, funcionario.getId());
			query.setString(2, funcionario.getNome());
			query.setString(3, funcionario.getSobrenome());
			query.setString(4, funcionario.getCargo());
			query.setDouble(5, funcionario.getSalario());

			// Executa SQL
			query.execute();
			query.close();
			return true;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return false;
	}

	@Override
	public boolean updateFuncionario(Funcionario funcionario) {

		// Define SQL
		sql = "UPDATE FUNCIONARIOS SET ID_FUNCIONARIO = ?, NOME = ?, SOBRENOME = ?,"
				+ " CARGO = ?, SALARIO = ? WHERE ID_FUNCIONARIO = ?";

		try {

			// Prepara SQL e alimenta parametros
			PreparedStatement query = conn.prepareStatement(sql);
			query.setLong(1, funcionario.getId());
			query.setString(2, funcionario.getNome());
			query.setString(3, funcionario.getSobrenome());
			query.setString(4, funcionario.getCargo());
			query.setDouble(5, funcionario.getSalario());
			query.setLong(6, funcionario.getId());

			// Executa SQL
			query.execute();
			query.close();
			return true;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return false;
	}

	@Override
	public boolean deletaFuncionario(Funcionario funcionario) {

		// Define SQL
		sql = "DELETE FROM FUNCIONARIOS WHERE ID_FUNCIONARIO = ?";

		// Prepara SQL e alimenta parametros
		PreparedStatement query;
		try {
			// Executa SQL
			query = conn.prepareStatement(sql);
			query.setLong(1, funcionario.getId());
			query.execute();
			query.close();

			return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return false;

	}

}

GUI – DAApp

package org.desenvolvimento.aberto;

import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;

import org.desenvolvimento.aberto.dao.FuncionarioDAO;
import org.desenvolvimento.aberto.modelo.Funcionario;

public class DAApp implements ActionListener {
	// Declara componentes
	private JLabel ltitulo;
	private JLabel lid;
	private JLabel lpnome;
	private JLabel lsnome;
	private JLabel lcargo;
	private JLabel lsalario;
	private JLabel lpesquisa;

	private JTextField tid;
	private JTextField tpnome;
	private JTextField tsnome;
	private JTextField tcargo;
	private JTextField tsalario;
	private JTextField tpesquisa;

	private JButton botao;
	private JButton alterar;
	private JButton inserir;
	private JButton deletar;
	private JButton novo;

	private Border borda;

	private JFrame menssagem;

	public Container criaPainel() {
		// cria painel
		JPanel painel = new JPanel();
		painel.setLayout(new FlowLayout());
		painel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
		painel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
		// Cria titulo
		ltitulo = new JLabel("Database - Fields -Sem conexão");

		painel.add(ltitulo);
		painel.add(Box.createVerticalStrut(60));

		// Cria painel de usuario
		JPanel painelDados = new JPanel(new GridLayout(0, 2, 10, 10));

		// Cria componentes
		lid = new JLabel("Código:");
		lpnome = new JLabel("Primeiro Nome:");
		lsnome = new JLabel("Sobrenome:");
		lcargo = new JLabel("Cargo:");
		lsalario = new JLabel("Salário:");

		tid = new JTextField();
		tpnome = new JTextField();
		tsnome = new JTextField();
		tcargo = new JTextField();
		tsalario = new JTextField();

		tid.setPreferredSize(new Dimension(150, 20));

		// Adiciona componentes no painel
		painelDados.add(Box.createVerticalStrut(10));
		painelDados.add(Box.createVerticalStrut(10));
		painelDados.add(lid);
		painelDados.add(tid);
		painelDados.add(lpnome);
		painelDados.add(tpnome);
		painelDados.add(lsnome);
		painelDados.add(tsnome);
		painelDados.add(lcargo);
		painelDados.add(tcargo);
		painelDados.add(lsalario);
		painelDados.add(tsalario);
		painelDados.add(Box.createVerticalStrut(10));
		painelDados.add(Box.createVerticalStrut(10));

		// Cria painel de pesquisa
		JPanel painelPesquisa = new JPanel(new GridLayout(0, 3, 10, 10));
		borda = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
		painelPesquisa.setBorder(borda);

		// Cria pesquisas
		lpesquisa = new JLabel("Pesquisa código:");
		tpesquisa = new JTextField();
		botao = new JButton("Pesquisar");
		botao.addActionListener(this);

		// Define foco do cursor no campo de pesquisa
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				tpesquisa.requestFocus();
			}
		});

		// Adiciona compoentes ao painel de pesquisa
		painelPesquisa.add(lpesquisa);
		painelPesquisa.add(tpesquisa);
		painelPesquisa.add(botao);

		// Cria painel de pesquisa
		JPanel painelAcao = new JPanel(new GridLayout(0, 4, 10, 10));
		borda = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
		painelAcao.setBorder(borda);

		// Cria botões de manipulação de banco
		novo = new JButton("Novo");
		inserir = new JButton("Inserir");
		alterar = new JButton("Alterar");
		deletar = new JButton("Apagar");

		// Cria ouvintes de eventos
		novo.addActionListener(this);
		inserir.addActionListener(this);
		alterar.addActionListener(this);
		deletar.addActionListener(this);

		// Insere componentes em um painel
		painelAcao.add(novo);
		painelAcao.add(inserir);
		painelAcao.add(alterar);
		painelAcao.add(deletar);

		// Adiciona paineis
		painel.add(painelPesquisa);
		painel.add(painelDados);
		painel.add(painelAcao);

		return painel;
	}

	// Clique do botão de pesquisa
	public void actionPerformed(ActionEvent arg0) {

		// Verifica pesquisa
		if (arg0.getSource() == botao) {

			// Cria funcionario
			Funcionario funcionario = new Funcionario();

			// Busca funcionario
			funcionario = new FuncionarioDAO().buscaFuncionario(tpesquisa
					.getText());

			// verifica resultado
			long resultado = funcionario.getId();

			// Alimenta dados na GUI
			if (resultado != 0) {
				tid.setText(String.valueOf(funcionario.getId()));
				tpnome.setText(funcionario.getNome());
				tsnome.setText(funcionario.getSobrenome());
				tcargo.setText(funcionario.getCargo());
				tsalario.setText(String.valueOf(funcionario.getSalario()));
			} else {

				JOptionPane.showMessageDialog(menssagem,
						"Funcionario não encontrado!");

				javax.swing.SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						tpesquisa.requestFocus();
						tpesquisa.selectAll();
					}
				});
			}
		}

		// Botão Novo
		if (arg0.getSource() == novo) {

			// Limpa GUI
			tid.setText(null);
			tpnome.setText(null);
			tsnome.setText(null);
			tcargo.setText(null);
			tsalario.setText(null);

			javax.swing.SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					tid.requestFocus();
				}
			});

		}

		// Insere dados
		if (arg0.getSource() == inserir) {

			// Cria funcionario usando o construtor Overload
			Funcionario funcionario = new Funcionario(Integer.parseInt(tid
					.getText()), tpnome.getText(), tsnome.getText(),
					tcargo.getText(), Double.parseDouble(tsalario.getText()));

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

			// Insere funcionario
			boolean resultado = inserir.insereFuncionario(funcionario);

			// Exibe resultado
			if (resultado) {
				JOptionPane.showMessageDialog(menssagem,
						"Dados inseridos com sucesso!");
			} else {
				JOptionPane.showMessageDialog(menssagem,
						"Erro ao inserir Dados!");
			}

		}

		// Altera dados
		if (arg0.getSource() == alterar) {

			// Cria funcionario usando o construtor overload
			Funcionario funcionario = new Funcionario(Integer.parseInt(tid
					.getText()), tpnome.getText(), tsnome.getText(),
					tcargo.getText(), Double.parseDouble(tsalario.getText()));

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

			// Altera funcionario
			boolean resultado = alterar.updateFuncionario(funcionario);

			if (resultado) {
				JOptionPane.showMessageDialog(menssagem,
						"Dados alterados com sucesso!");
			} else {
				JOptionPane.showMessageDialog(menssagem,
						"Erro ao alterar Dados!");
			}

		}

		// Deleta dados
		if (arg0.getSource() == deletar) {

			// Cria funcionario utilizando o construtor overload
			Funcionario funcionario = new Funcionario(Integer.parseInt(tid
					.getText()), tpnome.getText(), tsnome.getText(),
					tcargo.getText(), Double.parseDouble(tsalario.getText()));

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

			// Deleta funcionario
			boolean resultado = apagar.deletaFuncionario(funcionario);

			// Exibe resultado
			if (resultado) {
				JOptionPane.showMessageDialog(menssagem,
						"Dados apagados com sucesso!");

				javax.swing.SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						tpesquisa.requestFocus();
						tpesquisa.selectAll();
					}
				});

				novo.doClick();
			} else {

				JOptionPane.showMessageDialog(menssagem,
						"Erro ao apagar Dados!");

			}
		}

	}

	public static void criaGUI() {
		// Cria formulario
		JFrame formulario = new JFrame("Desenvolvimento Aberto");
		formulario.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// cria painel de conteudo
		DAApp app = new DAApp();

		formulario.setContentPane(app.criaPainel());

		// Exibe o formulario
		formulario.setSize(400, 450);
		formulario.setVisible(true);

	}

	public static void main(String[] args) {

		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {

				// Mostra GUI
				criaGUI();

			}
		});

	}

}

 

O WAS Liberty Porfile é extremamente leve, fácil de instalar, e muito rápido de usar, portanto, fornece uma plataforma conveniente e capaz para desenvolver e testar suas aplicações web e OSGi. Permite que o servidor de aplicação tenha a disposição apenas os recursos necessários para o aplicativo ou conjunto de aplicações, você também pode estender os recursos do servidor de aplicação instalando um pacote de extensão para adicionar mais funcionalidades ao Liberty Profile como recursos de Web Service, JMS e suporte ao MongoDB entre outros. Você também pode adicionar um pacote de extras que permite utilizar um Embeddable EJB Container e um cliente JPA .

WAS Developer Edition: http://www-03.ibm.com/software/products/pt/appserv-wasfordev

Instalando Pacotes de Extensão e Extras

1 – Na pagina de download após o login escolha os seguintes softwares: IBM WebSphere Application Server for Developers Extended Archive e IBM WebSphere Application Server for Developers Extra Archive , são arquivos de extensão jar:

Download Extended e Extras

Download Extended e Extras

2 – Abra o prompt de comando no local onde instalou o servidor e utilize o seguinte comando para instalar a extensão:

java -jar wlp-developers-extended-8.5.5.4.jar
Extendes Archive

Extendes Archive

3 – Pressione Enter para exibir os termos de licença e digite 1 para confirmar a instalação:

Termos de Licença

Termos de Licença

4 – Pressione Enter para confirmar o local da instalação, você deve instalar no mesmo diretório do runtime do servidor WAS:

Local da Instalação

Local da Instalação

5 – Aguarde o andamento e validação da instalação:

Validação

Validação

6 – Repita o mesmo procedimento com o arquivo de extras porem você pode criar uma pasta chamada Extras para a instalação:

Exemplo: C:\Desenvolvimento Aberto\IBM\extras
java -jar wlp-developers-extras-8.5.5.4.jar

 Configurando o WAS Liberty Profile

 7 – Abra o Eclipse e a aba Servers e expanda o servidor Websphere Application Server Liberty Profile. Expanda a opção Server Configuration e em Feature Manager clique com o botão direito e escolha Open:

Server Configuration

Server Configuration

8 – Na opção Feature Manager clique no botão Add para adicionar mais funcionalidades ao servidor:

Feature Manager

Feature Manager

9 – Adicione a funcionalidade adequada a sua aplicação:

Estenção

Funcionalidades

Você pode adicionar somente as funcionalidades que você precisa para suas aplicações e utilizar vários recursos da já consagrada tecnologia JAVA EE e OSGI (Open Services Gateway Initiative) que permite a reutilização de componentes para construir e gerenciar sistemas altamente complexos. Tornando o código mais fácil de escrever, testar e reutilizar. Gerenciar implantação dinâmica. Detectar erros previamente. Implantar remotamente. Detectar e resolver problemas que ainda não aconteceram.

O conjunto de ferramentas para desenvolvedores WebSphere Develper Tools é um plug-in para a IDE Eclipse para a construção e implantação de aplicações Java EE, OSGi e aplicações Web 2.0 para o WebSphere Application Server Liberty Profile. As ferramentas proporcionam um meio fácil e leve para o desenvolvimento, montagem e implantação de aplicativos para o WebSphere Application Server.

Para instalar basta acessar o menu Help do Eclipse e escolher a opção Eclipse MarketPlace e digitar na busca a palavra WebSphere, selecione a versão da sua IDE, clique em instalar e você obterá ajuda do assistente de instalação:

WebSphere Developer Tools for Eclipse

WebSphere Developer Tools for Eclipse

Configurando o WAS Liberty Profile no Eclipse

1 – Abra janela de servidores crie um novo servidor, você pode fazer isto de varias maneiras no Eclipse uma delas é no menu Window->Show View->Server. Na janela de servidores, clique com o botão direito e escolha New Server:

New Server

New Server

2 – Caso ainda não tenha o adaptador para servidor WAS Liberty Profile, clique em Download additional servers adapter e escolha o adaptador para o servidor:

WAS Liberty Profile Adapter

WAS Liberty Profile Adapter

3 – Aceite os termos de licença e clique em instalar:

Was Adapter - Licença

Was Adapter – Licença

4 – Escolha a opção para seu servidor e clique em Next:

Novo Servidor

Novo Servidor

5 – Escolha o caminho da instalação do servidor WebSphere Application Server Liberty Profile na maquina local, o Java JRE e clique em Finish:

WASLF - Configuração

WASLF – Configuração

Testando o WAS Liberty Profile

6 – Para testar o servidor na aba Servers selecione o WAS Liberty Profile e crie um novo projeto do tipo Dynamic Web Project, crie um Servlet chamado DaWebSphereHelloWorld,  utilize o código abaixo, rode sua aplicação e selecione o servidor adequado:

Run - WAS

Run – WAS

7 – Pronto, sua aplicação já está rodando:

WebSphere Application Server

WebSphere Application Server

O conceito do WebSphere Application Server Liberty Profile é proporcionar um ambiente leve e rápido para aplicações Java e OSGI carregando somente os Containers e recursos necessários para as aplicações, entretanto caso queira utilizar outros recursos você precisa efetuar uma instalação adicional de extras para o servidor WebSphere Application Server.

WasDev: https://developer.ibm.com/wasdev/downloads/

Was for Developer e Extras: http://www-03.ibm.com/software/products/pt/appserv-wasfordev

WAS Extended e Extras: Instalação e configuração.

Exemplo:

Neste exemplo configuramos o instalamos as ferramentas WAS Liberty Profile para o Eclipse e configuramos o servidor na IDE para que possamos desenvolver aplicações Java para o IBM WebSphere.

Java

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DaWebSphereHelloWorld")
public class DaWebSphereHelloWorld extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public DaWebSphereHelloWorld() {
		super();

	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Cria Página HTML Dinâmica
        response.setContentType("text/html");

        PrintWriter html = response.getWriter();

        html.println("<html>");
        html.println("<body>");
        html.println("<h1>Desenvolvimento Aberto - Java</h1>");
        html.println("<h2>IBM WebSphere Application Server for Developers Edition</h2>");
        html.println("<h3>WAS Liberty Profile Server - Instalação: Standalone</h3>");
        html.println("</form>");
        html.println("</body>");
        html.println("</html>");

	}

}

O WebSphere Application Server é um produto de software que executa o papel de um servidor de aplicativos web. Mais especificamente, é uma estrutura de software e middleware que hospeda aplicativos web baseados em Java. O WAS é o principal produto dentro da suíte de software IBM WebSphere.

O WAS Liberty Porfile é um perfil dinâmico do WebSphere Application Server que permite que o servidor de aplicação tenha a disposição apenas os recursos necessários para o aplicativo (ou conjunto de aplicações) implantadas no servidor WAS. Se uma aplicação requer apenas um mecanismo de Servlet, então tudo o que o servidor iniciará é o kernel, o transporte HTTP e o contêiner web.  O WAS é encontrado para download na versão WebSphere Application Server Full Profile e em uma versão de instalação Standalone do servidor Liberty Profile.

WAS Developer Edition: http://www-03.ibm.com/software/products/pt/appserv-wasfordev

Instalando e Configurando o WAS for Developers Liberty Profile

1 – Na pagina de download após o login (caso não tenha um ID da IBM crie um gratuitamente) escolha o seguinte software: IBM WebSphere Application Server for Developers Archive, ele é um arquivo de extensão jar:

WAS for Developers - Download

WAS for Developers – Download

2 – Abra o prompt de comando e utilize o seguinte comando para instalar o WAS:

java -jar wlp-developers-runtime-8.5.5.2.jar
Instalando - Jar

Instalando – Jar

3 – Pressione Enter para exibir os termos de licença e digite 1 para confirmar a instalação:

Termos de Licença

Termos de Licença

4 – Pressione Enter para confirmar o local da instalação ou entre o local desejado:

Local da instalação

Local da instalação

5 – Aguarde o andamento da instalação:

Andamento

Andamento

6 – Após a instalação precisamos criar e iniciar um servidor WAS, digite os seguintes comandos:

cd wpl\bin
server create DA001
server start DA001
Criando e Iniciando o Servidor

Criando e Iniciando o Servidor

7 – Para testar abra o navegado e digite a seguinte url: http://localhost:9080/

WebSphere Application Server Liberty Profile

WebSphere Application Server Liberty Profile

Agora você precisa instalar as ferramentas para desenvolvimento WAS Developer Tools para o Eclipse e programar aplicações Java baseadas no servidor de aplicação IBM WebSphere. Para instalar as ferramentas para o Eclipse e criar uma aplicação Hello World com WAS Liberty Profile clique aqui.