Revista Eletrônica da Faculdade Metodista Granbery http://re.granbery.edu.br - ISSN 1981 0377 Curso de Sistemas de Informação - N. 6, JAN/JUN 2009 TUTORIAL SOBRE A CONSTRUÇÃO DE APLICAÇÕES EMPREGANDO JAVA, HIBERNATE E MySQL Elio Lovisi Filho 1 Gustavo Mendes de Castro 2 RESUMO Este artigo apresenta o desenvolvimento de um exemplo de sistema para manutenção de dados de departamentos. Apresentam-se aqui as técnicas e as ferramentas empregadas nesse desenvolvimento, bem como os resultados obtidos durante a realização do mesmo. Esse sistema foi desenvolvido empregando-se o paradigma da Orientação a Objetos, o Java, a IDE NetBeans 6.5, o framework Hibernate e o SGBD MySQL. PALAVRAS-CHAVE: JAVA, MVC, DAO, HIBERNATE E MYSQL. ABSTRACT This article presents the development of an example system for maintenance of data from departments. The techniques and the tools used in this development are presented here, as well as the results gotten during his accomplishment. This system was developed using the Object-Oriented paradigm, the Java, the NetBeans 6.5 IDE, the Hibernate framework and the MySQL DBMS . KEY-WORDS: JAVA, HIBERNATE, MVC, DAO,E MYSQL. 1 - Mestre em Informática pelo Instituto Tecnológico de Aeronáutica, Professor do curso de Sistemas de Informação da Faculdade Metodista Granbery e Analista de Sistemas da Prefeitura de Juiz de Fora. Email:[email protected] 2 - Graduado em Sistemas de Informação pela Faculdade Metodista Granbery e programador da Prefeitura de Juiz de Fora. Email:[email protected] 1. INTRODUÇÃO Apresenta-se aqui o desenvolvimento de um exemplo acadêmico de caso de uso, que implemente as operações básicas de acesso a um banco de dados, empregando a abordagem MVC e o padrão de projetos DAO. Não será apresentada a implementação de todas as funções de um aplicativo profissional. A abordagem MVC - Modelo, Visão e Controle (Model, View and Controller) define como os componentes da aplicação irão interagir entre si. Este padrão de arquitetura divide os objetos em três conjuntos: o Modelo (Model), composto por objeto de entidade da aplicação; a Visão (View), composta por objetos de apresentação na tela; e o Controlador (Controller), que possui objetos que definem a maneira como a interface do usuário reage às entradas do mesmo. (GAMMA et al., 2000). Além disso, para a manipulação dos dados do sistema foram empregados objetos de acesso, conhecidos como DAO (Data Access Object), que permitem que as regras de negócio sejam separadas das regras para acesso aos dados, de forma que sejam criadas classes exclusivas para o acesso ao SGBD (XAVIER, 2007). A aplicação desenvolvida empregará a linguagem de programação JAVA, que é uma linguagem de programação orientada a objetos. No entanto, a maioria dos SGBD's utilizados atualmente emprega o modelo relacional. Logo, existe a necessidade de realizar a “tradução” entre os dois modelos. Para tanto será empregado o framework Hibernate. (KING, 2007) As ferramentas empregadas no desenvolvimento deste tutorial foram: a IDE NetBeans 6.5, disponível para donwload em http://www.netbeans.org/; o SGBD MySQL, que pode ser obtido no site: http://www.mysql.com/; e a ferramenta SQLyog para a administração do SGBD, disponível no site http:// www.webyog.com. No entanto, qualquer ferramenta para administração de um SGBD MySQL poderá ser empregada. Nos próximos itens serão apresentadas as atividades necessárias para a criação de um exemplo de aplicativo Java que acesse um banco de dados MySQL empregando o framework Hibernate, utilizando também os padrões MVC e DAO. 2. PREPARANDO O AMBIENTE Conforme citado anteriormente, para o desenvolvimento desse aplicativo será 2 empregado o SGBD MySQL. Para esse tutorial foi criado um banco de dados chamado exemplohibernate, com o usuário root e a senha vazia. Nesse banco crie a tabela departamento utilizando o script abaixo: CREATE TABLE `departamento` ( `id` int(11) NOT NULL auto_increment, `nome` varchar(60) default NULL, `area` varchar(60) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB Na ferramenta NetBeans 6.5 crie um novo projeto chamado ExemploHibernate, e inclua no seu pacote de código fonte (Source Package), os seguintes pacotes: DAO, model, control e view .(GONÇALVES,2006) Para este aplicativo será necessária a utilização das bibliotecas do Hibernate JPA e do driver JDBC que fará o acesso ao banco. Logo, será necessária a construção de Librarys no NetBeans para o armazenamento e organização destes arquivos. Para isso, deve-se criar uma Library para o driver JDBC do MySQL. O NetBeans permite a construção de Librarys através da opção Library Manager no menu Tools. Ao escolher esta opção a janela Library Manager será aberta e basta clicar no botão New Library... no canto inferior esquerdo da mesma como na figura a seguir. Figura 01. Gerência de bibliotecas no NetBeans. Na figura anterior, selecione a opção New Library... para criar a biblioteca JDBCMySql, adicionando o arquivo: mysql-connector-java-3.1.11-bin.jar (ou uma versão 3 mais recente), disponível em http://www.findjar.com. Adicione as bibliotecas (Hibernate JPA e JDBCMySql) ao projeto. Para isso, vá ao inspetor de Projetos e clique com o botão direito sobre o item bibliotecas (Libraries) e escolha Adicionar Bibliotecas (Add Library), conforme a figura a seguir. Figura 02. Adicionando bibliotecas ao projeto no NetBeans. No pacote padrão (default package) crie um arquivo de configuração (New – Other – Properties File) chamado hibernate.properties, e insira o código abaixo: hibernate.dialect org.hibernate.dialect.MySQLDialect hibernate.connection.driver_class com.mysql.jdbc.Driver hibernate.connection.url jdbc:mysql://localhost:3306/exemplohibernate hibernate.connection.username root hibernate.connection.password hibernate.show_sql false hibernate.format_sql false Observe que neste arquivo são estabelecidos os parâmetros de configuração da conexão do aplicativo com o SGBD. A propriedade url define a localização e a porta do banco de dados. Já as propriedades username e password definem o usuário e a senha de acesso ao banco de dados. 3. CRIANDO A CLASSE DE MODELO (MODEL) No pacote model crie a classe Departamento, com um construtor padrão (vazio) e com os seguintes atributos encapsulados: id (Integer) nome (String) area (String) Agora, será necessário mapear a classe Departamento da aplicação à tabela departamento do SGBD. Isso é necessário para indicar qual(is) tabela(s) do banco de dados corresponde(m) à classe de entidade, empregando-se um mapeamento que indica essa correspondência.(KING, 2007) 4 Nesse exemplo faremos o mapeamento por meio de anotações na classe. Altere a classe Departamento conforme a figura abaixo. Figura 03. Mapeamento da classe de modelo As anotações (precedidas por '@') indicam o mapeamento entre a classe e a tabela do banco de dados. Algumas importações do pacote javax.persistence serão necessárias nesse ponto. 4. CONSTRUINDO A FACTORY CLASS Para evitar a dependência entre o aplicativo principal e a implementação concreta do DAO, iremos empregar o padrão Factory Method, no qual um objeto é responsável pela criação de outros, “fabricando-os”. (XAVIER, 2007) Sendo assim, nosso próximo passo consiste em construir a classe FactoryClass para gerência do Banco de Dados a ser utilizado. Para isso, crie uma nova classe no pacote DAO e dê o nome para ela de FactoryClass. Em seguida, digite o código mostrado a seguir. public static void criarDAOFactory() { HibernateConfiguracao configuracao = new HibernateConfiguracao(); configuracao.criaSessionFactory(); } Nesse ponto, algumas linhas do seu código irão ficar marcadas de vermelho. No mesmo pacote, crie a classe HibernateConfiguracao, com o seguinte código. public class HibernateConfiguracao { private static SessionFactory sessionFactory; public HibernateConfiguracao() { } public Session openSession() { return sessionFactory.openSession(); } public void criaSessionFactory() { if (sessionFactory == null) { AnnotationConfiguration cfg = new AnnotationConfiguration(); cfg.addAnnotatedClass(Departamento.class); sessionFactory = cfg.buildSessionFactory(); } } } 5 Neste momento será necessário importar algumas classes do Hibernate. 5. CRIANDO O DAO A classe DAO irá permitir o acesso do sistema ao SGBD configurado. Para tanto, iremos utilizar um DAO Genérico que possui os métodos básicos de acesso a um banco de dados. Incluir; Alterar; Excluir; Consultar; Listar. Para a execução dessas operações básicas, pode-se empregar alguns métodos genéricos, como os listados abaixo. Para tanto, crie uma classe chamada DAOGenerico (no pacote DAO), com o código exibido a seguir.(KING, 2007) public class DAOGenerico { protected HibernateConfiguracao hibernateConfiguracao; public DAOGenerico() { hibernateConfiguracao = new HibernateConfiguracao(); } public void gravar(Object obj) throws HibernateException { Session session = hibernateConfiguracao.openSession(); Transaction transaction = session.beginTransaction(); session.save(obj); transaction.commit(); session.close(); } public void alterar(Object obj) throws HibernateException { Session session = hibernateConfiguracao.openSession(); Transaction transaction = session.beginTransaction(); session.update(obj); transaction.commit(); session.close(); } public void excluir(Object obj) throws HibernateException { Session session = hibernateConfiguracao.openSession(); Transaction transaction = session.beginTransaction(); session.delete(obj); transaction.commit(); session.close(); } public List carregarTudoOrdenado(Class clas, String ordem) HibernateException { Session session = hibernateConfiguracao.openSession(); Criteria criteria = session.createCriteria(clas); criteria.addOrder(Order.asc(ordem)); List lista = criteria.list(); session.close(); throws 6 return lista; } public Object carregarUm(int id, Class clas) throws HibernateException { Session session = hibernateConfiguracao.openSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(clas); criteria.add(Expression.eq("id", id)); Object obj = criteria.uniqueResult(); transaction.commit(); session.close(); return obj; } } Para esta classe, serão necessárias as seguintes importações: import java.util.List; import org.hibernate.Criteria; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Expression; import org.hibernate.criterion.Order; No mesmo pacote, crie o DAODepartamento, herdando do DAOGenerico e com um construtor próprio. 6. CONSTRUINDO O CONTROLADOR (CONTROLLER) No pacote control, crie uma nova classe, chamada CtrManterDepartamento. Nessa classe crie um atributo utilizando o seguinte código: DAODepartamento acessohibernatedepto = new DAODepartamento(); Após isso inclua o código a seguir. public CtrManterDepartamento( ){ } public int gravarDepartamento(Departamento departamento) { try { acessohibernatedepto.gravar(departamento); return 1; } catch (HibernateException e) { e.printStackTrace(); return 2; } } 7. CONSTRUINDO O FORMULÁRIO (VIEW) Num primeiro momento, iremos criar um formulário que permita somente a inclusão dos departamentos. Para isso, no pacote view, crie um novo JFrame, chamado 7 FrmManterDepartamento. (GONÇALVES,2006) Insira um JButton “Incluir” (jBtnIncluir) e dois JtextField (jTxtNome, jTxtArea) para o nome e a área do departamento. Após isso, crie 2 atributos no código do formulário, conforme o apresentado abaixo. CtrManterDepartamento ctrManterDepartamento = new CtrManterDepartamento(); Departamento depart = new Departamento(); Crie um evento para o botão (Events – Action – actionPerformed) e insira o código a seguir no evento criado. depart.setNome(jTxtNome.getText()); depart.setArea(jTxtArea.getText()); if (ctrManterDepartamento.gravarDepartamento(depart) == 1) { JOptionPane.showMessageDialog(this, "Objeto persistido"); } else { JOptionPane.showMessageDialog(this, "Objeto não persistido"); } A seguir, é mostrado um exemplo deste JFrame. Figura 04. Tela para manutenção de dados 8. CONSTRUINDO O A TELA INICIAL DA APLICAÇÃO No pacote padrão, crie mais um JFrame, chamado Principal, inclua nele um Jbutton (chamado jBtnExibirDepartamento), torne essa classe a inicial do sistema e faça as seguintes alterações na classe: //construtor public Principal() { FactoryClass.criarDAOFactory(); initComponents(); } //método main public static void main(String args[]) { Principal telaPrincipal = new Principal(); telaPrincipal.setVisible(true); 8 telaPrincipal.setExtendedState(MAXIMIZED_BOTH); } Agora crie um evento actionPerformed no botão e insira o seguinte código. FrmManterDepartamento telaDepartamento = new FrmManterDepartamento(); telaDepartamento.setVisible(true); telaDepartamento.setLocationRelativeTo(this); Nesse momento o aplicativo já deve permitir a inclusão de departamentos. Execute o programa para avaliar os resultados. Se desejar, inclua o código para limpar os campos, caso o departamento seja inserido corretamente. Além disso, incluir também códigos para validação dos atributos, observando o tamanho máximo dos registros no banco de dados. Por enquanto, para visualizar o resultado da execução, utilize a ferramenta SQLyog. 9. LISTANDO OS OBJETOS Para permitir a visualização dos dados, insira um componente JList no formulário FrmManterDepartamento e faça as seguintes alterações: Aumente a largura da lista; Altere o nome para jLstDepartamentos; Remova todos os itens de sua propriedade model; e Altere a propriedade selectionMode para Single. O formulário deve ficar com a seguinte aparência. Figura 05. Tela para manutenção de dados alterada para permitir a listagem dos objetos. 9 A seguir, inclua um novo evento no JFrame (Window – windowActiveted), insira o código no evento criado e importe as classes necessárias. DefaultListModel listModel = new DefaultListModel(); List listDepartamento = new ArrayList(); listDepartamento = ctrManterDepartamento.carregarDepartamentos(); if (listDepartamento != null) { Iterator i = listDepartamento.iterator(); while (i.hasNext()) { Departamento deptList = (Departamento) i.next(); listModel.addElement(deptList); } jLstDepartamentos.setModel(listModel); } else { JOptionPane.showMessageDialog(this, "Não foi possível recuperar todos os departamentos"); } O sistema ainda irá indicar que falta um método no controlador. Para corrigir este problema, inclua o código abaixo no controlador e faça as importações necessárias. public List carregarDepartamentos() { try { return acessohibernatedepto.CarregarTudoOrdenado (Departamento.class, "nome"); } catch (HibernateException e) { return null; } } Finalmente, insira o método abaixo na classe Departamento do pacote model. public String toString() { return this.getNome(); } Observe que a lista foi preenchida com objetos da classe departamento. Logo, a consulta aos dados de um objeto ficou muito mais simples. Para exibir os dados de um objeto selecionado na lista, crie um novo evento para a lista (Mouse – mouseClicked) e acrescente o código a seguir ao evento: depart = (Departamento) jLstDepartamentos.getSelectedValue(); if (depart != null) { jTxtNome.setText(depart.getNome()); jTxtArea.setText(depart.getArea()); } else { JOptionPane.showMessageDialog(this, "Objeto não Encontrado!"); } Nesse momento, a execução do programa deverá permitir a inclusão dos objetos da classe departamento, e também a listagem e consulta dos mesmos. 10 10. EXCLUINDO OS OBJETOS Iremos agora permitir a exclusão de departamentos. Para tanto, inclua um novo Jbutton, altere sua propriedade Text para “Excluir” e sua propriedade Name para “jBtnExcluir”. Após isso, crie um evento para o novo botão (Events – Action – actionPerformed) e insira o código abaixo. depart = (Departamento) jLstDepartamentos.getSelectedValue(); if (depart != null) { if (ctrManterDepartamento.excluirDepartamento(depart)) { JOptionPane.showMessageDialog(this, "Objeto Excluído"); } else { JOptionPane.showMessageDialog(this, "Objeto não excluído"); } } else { JOptionPane.showMessageDialog(this, "Selecione o Objeto"); } Novamente o sistema irá indicar que falta um método no controlador. Logo, insira o código abaixo no controlador. public boolean excluirDepartamento(Departamento departamento) { try { acessohibernatedepto.excluir(departamento); return true; } catch (HibernateException e) { e.printStackTrace(); return false; } } 11. ALTERANDO OBJETOS Agora vamos possibilitar a alteração de um objeto selecionado na lista. Para tanto, inclua um novo botão na tela, conforme exibido na figura a seguir. Modifique sua propriedade texto para “Alterar”, a sua propriedade Name para jBtnAlterar e crie um novo evento (Events – Action – actionPerformed) para o novo botão. 11 Figura 06. Tela para manutenção de dados permitindo a listagem, inclusão, alteração e exclusão de objetos. Insira o código abaixo no evento criado para o botão. depart = (Departamento) jLstDepartamentos.getSelectedValue(); if (depart != null) { depart.setNome(jTxtNome .getText()); depart.setArea(jTxtArea .getText()); if (ctrManterDepartamento.alterarDepartamento(depart)) { JOptionPane.showMessageDialog(this, "Objeto persistido"); } else { JOptionPane.showMessageDialog(this, "Objeto não persistido"); } } else { JOptionPane.showMessageDialog(this, "Objeto não localizado"); } Após isso, altere o controlador inserindo o código abaixo. public boolean alterarDepartamento(Departamento departamento) { try { acessohibernatedepto.alterar(departamento); return true; } catch (HibernateException e) { e.printStackTrace(); return false; } 12 } Finalmente, execute o programa e observe os resultados. Se desejar, limpe os campos da tela após a alteração e a exclusão do objeto. 12. CONSIDERAÇÕES FINAIS O objetivo deste artigo foi apresentar o desenvolvimento de um exemplo de sistema computacional multi-camada empregando a linguagem de programação Java, o framework Hibernate e o SGBD MySQL. A utilização da IDE NetBeans apresentou bons resultados, agilizando o processo de desenvolvimento. Além disso, o emprego do framework simplificou o processo de persistência dos dados. A classe DAOGenerico foi desenvolvida buscando-se manter o encapsulamento. Sendo assim, ela poderá ser facilmente reutilizada em outros sistemas. Propõe-se a aplicação, em trabalhos futuros, de outras formas de interação entre os objetos das camadas do sistema, em especial com a aplicação do MVP (Passive View, Supervising Controller). Pode-se também desenvolver outras formas de interação com o usuário, aplicando-se diferentes tecnologias como Web ou Mobile. 13 13. REFERÊNCIAS BIBLIOGRÁFICAS DEITEL, H. M.. Java Como Programar. 6a ed. São Paulo: Prentice Hall, 2007. GAMMA, E; HELM, R; JOHNSON, R; VLISSIDES, J. Padrões de projeto: soluções reutilizáveis de software orientado a objetos, Porto Alegre: Bookman, 2000. GONÇALVES, Edson. Dominando NetBeans. Rio de Janeiro: Ciência Moderna, 2006. KING G. Java Persistence com Hibernate. Rio de Janeiro: Ciência Moderna, 2007. XAVIER, K.; SENGER, Y. Abstract Factory Aplicado. Rio de Janeiro, Java Magazine, edição 50, p. 40-45, 2007. 14