quarta-feira, 19 de setembro de 2012

JAVA + Spring + Netbeans 7.2 - Mysql Lesson 04

Dando seqüência nos post de JAVA + Spring

Requisitos :
- Netbeans 7.2
- spring-3.2.0.M2

- Ter lido :

Posts Anteriores : 
JSNBTut - Base  que é uma preparação do ambiente para o desenvolvimento

Opcionais : 
JSNBTut - Lesson 01 - introdução ao Spring

JSNBTut - Lesson 02 - introdução ao gerenciamento de dependências no  Spring

Opcional :
JSNBTut - Lesson 03 - acessando banco de dados Mysql com beans e injeção de dependências

Este é o 4º da série , o objetivo deste post é mostrar um outro jeito rápido de utilizar o Spring e Mysql sem utilizar Arquivos XML.

Caso já tenha lido a lesson 03, e baixado o arquivo do mysqlWorkbench, esta tabela contato já esta no arquivo springLessons.mwb, basta mandar sincronizar com o servidor Mysql.

Se não leu, crie o banco  conforme informado abaixo :
- Criar um banco de dados Mysql : chamarei de springlessons, logue como root em um banco Mysql e crie o usuario e o banco :

CREATE USER 'springlessons'@'%' IDENTIFIED BY 'DHADdSXcDF29WGXy';

GRANT ALL PRIVILEGES ON * . * TO 'springlessons'@'%' IDENTIFIED BY 'DHADdSXcDF29WGXy' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;

CREATE DATABASE IF NOT EXISTS `springlessons` ;

GRANT ALL PRIVILEGES ON `springlessons` . * TO 'springlessons'@'%';

Crie a tabela no banco de dados Mysql com o usuário springlessons :

CREATE  TABLE IF NOT EXISTS `springlessons`.`contato` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `nome` VARCHAR(45) NULL ,
  `telefone` VARCHAR(45) NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB


1 - Com o banco criado e configurado, abra o Netbeans e clique em File -> new Project :
Figura 01- Novo projeto


2 - Crie um projeto do Tipo Java --> Java Application

Figura 02- Novo projeto Java

3 - Informe o nome do projeto SpringLesson04, e altere o nome da classe principal para MainClass

Figura 03- Novo projeto SpringLesson04
Após a criação do projeto , voce deve estar visualizando isso :
Figura 04 - Projeto criado pelo wizard



4- Adicione as bibliotecas necessárias : Spring e o driver do Mysql

Figura 05- Adicionar Libs

no projeto,  voce deve estar visualizando isso :
Figura 06- Estado do projeto


Agora vamos começar a codificar. 

Podemos e vamos utilizar o NB p/ facilitar algumas coisas (geração de código)
5 - Vamos criar uma classe que faz parte M do modelo MVC, chamada Contato em um package springlesson04.model
Figura 07 -Clique com o botão direito em cima do projeto e escolha New>> Java Class
Figura 08-preencha : Class Name=Contato, Package=springlesson04.model
Adicione o seguinte código nesse arquivo Contato.java

    int id;
    String nome;
    String telefone;    



e vamos utilizar a técnica de refatoração/encapsulamento p/ terminar o código dessa classe:
Figura 09- Refatoração/Encapsulamento

Figura 10- Refatoração/Encapsulamento : Observe Javadoc:none p/ não gerar os comentários de cada atributo


e nossa classe  Contato.java deve ficar assim :

package springlesson04.model;

public class Contato {
    
    private int id;
    private String nome;
    private String telefone;

    public int 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 getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }
}
6 - Vamos criar a classe OrderDao. Clique com o botão direito no projeto e escolha New>> Java Class
Figura 11- preencha : Class Name=ContatoDAO, Package=springlesson04.dao
Nessa Classe iremos extender a classe JdbcDaoSupport do Spring (org.springframework.jdbc.core.support.JdbcDaoSupport).

e nossa classe  ContatoDAO.java deve ficar assim :


package springlesson04.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import springlesson04.model.Contato;

public class ContatoDAO extends JdbcDaoSupport {

    public ContatoDAO() {
    }
    
    public List<Contato> listar(){
        JdbcTemplate t = getJdbcTemplate();
        List<Contato> listaContatos=t.query("SELECT * FROM `springlessons`.`contato`", new RowMapper() {

            @Override
            public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                Contato C = new Contato();
                C.setId(rs.getInt("id"));
                C.setNome(rs.getString("nome"));
                C.setTelefone(rs.getString("telefone"));
                        return C;
                
            }
        });
        return listaContatos;
        
    }
    
}

7 - Vamos implementar na classe MainClass a chamada para isso que fizemos.
Troque o código existente neste arquivo pelo código abaixo : (esse é o famoso modo quick and dirty)

package springlesson04;

import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import springlesson04.dao.ContatoDAO;
import springlesson04.model.Contato;

public class MainClass {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        DataSource ds = new SingleConnectionDataSource(
                "com.mysql.jdbc.Driver",
                "jdbc:mysql://ns1/springlessons",
                "springlessons",
                "DHADdSXcDF29WGXy",
                true);// se a conexao é fechada automaticamente
        JdbcTemplate template = new JdbcTemplate(ds);
        ContatoDAO dao = new ContatoDAO();
        dao.setJdbcTemplate(template);
        
        for (Contato c: dao.listar()){
            System.out.println("id:" + c.getId() + "\tnome: " + c.getNome() + "\tTelefone:" + c.getTelefone());
        } // \t=tab       
        
        
    }
}
8- E .. clique em Run project
Figura 12- 1ª Compilação com sucesso 

Sep 19, 2012 3:42:35 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
INFO: Loaded JDBC driver: com.mysql.jdbc.Driver
Sep 19, 2012 3:42:36 PM org.springframework.jdbc.datasource.SingleConnectionDataSource initConnection
INFO: Established shared JDBC Connection: com.mysql.jdbc.JDBC4Connection@11bbf1ca
BUILD SUCCESSFUL (total time: 3 seconds)

Compilou?! Não deu erros ?
Se a resposta p/ as duas perguntas for : sim, podem surgir algumas dúvidas:
1 - Cadê os dados ? R: ainda não cadastramos
2 - O programa não deveria mostrar alguma coisa? R: Sim, vamos trabalhar nisso.

9 - Se ainda não existirem registros :
Vamos adicionar uma verificação na quantidade de Registros antes de mostrar.
Adicione o seguinte código antes do for 


        if (dao.listar().isEmpty()){
            System.out.println(" Sem contatos cadastrados");
        }

 .. clique em Run project
Figura 13-  e se não tiver registros ?

Sep 19, 2012 3:51:30 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
INFO: Loaded JDBC driver: com.mysql.jdbc.Driver
Sep 19, 2012 3:51:31 PM org.springframework.jdbc.datasource.SingleConnectionDataSource initConnection
INFO: Established shared JDBC Connection: com.mysql.jdbc.JDBC4Connection@49ff0dde
 Sem contatos cadastrados
BUILD SUCCESSFUL (total time: 3 seconds)


Simples né ? Para ilustrar esse exemplo e mostrar o uso do Spring + o Mysql e consultar uma tabela está bom?
Se a resposta for sim: 10
Se a resposta for não: 11

10 - Para ver o programa apresentar algum registro , vamos adicionar manualmente 2 registros em nosso banco, acesse o myqsl e insira 2 registros na tabela contato
obs: no final da lição 03, tem uma dica de como configurar a conexao entre o MyWorkBench e seu servidor Mysql

I) Clique duas vezes na conexão criada para o banco springlessons

Figura 14-  MYWKB - Conexao ao seu banco

II) Clique com o botão direito no banco springlessons e escolha a opção Set as default Schema
Figura 15 - MYWKB : Definindo o SCHEMA

 III) Clique com o botão direito na tabela contato e escolha Send to SQL Editor>> Insert Statement
Figura 16 - MYWKB : Criando Consultas

IV) Agora basta inserir 2 registros no sql gerado, lembre-se que o campo id é autoincrement e não precisa ser informado

INSERT INTO `springlessons`.`contato`
(
`nome`,
`telefone`)
VALUES
(
'Cliente 1',
'2222-3333'
);
INSERT INTO `springlessons`.`contato`
(
`nome`,
`telefone`)
VALUES
(
'Cliente 2',
'4444-5555'
);



V) Clique no Raio p/ executar o SQL


Figura 17 - MYWKB : Executar - o ícone do Raio 


e o resultado deve ter sido esse : 
Figura 18 - MYWKB : Executando Inserts

VI) Clique no 1º ícone (pagina com sinal de +) para abrir uma nova aba dentro do SQL-Editor
Figura 19 - MYWKB : Diferentes scripts em diferentes abas

VII) e com a nova aba aberta clique com o botão direito na tabela contato e escolha a opção Send to SQL Editor>>Select All Statement

Figura 20 - MYWKB : Gerando um select adequado
Codigo gerado :


SELECT
`contato`.`id`,
`contato`.`nome`,
`contato`.`telefone`
FROM `springlessons`.`contato`;

Obs: Quando você for utilizar consultas (em qualquer banco), NUNCA UTILIZE SELECT * ao implementar no programa. Isso é serviço de gente preguiçosa que não compreende o custo disso p/ o sistema, cpu, rede, etc.. e os nomes de objetos do banco no MYSQL devem ser informados individualmente entre o caracter ` (crase) como no exemplo acima. 

VIII) Conferindo os resultados : 
Clique no raio p/ executar a consulta e veja os dois clientes cadastrados 
Figura 21 - MYWKB : Resultado da consulta


IX) Vendo os dados cadastrados no programa :
Volte ao NB e clique novamente em Run>> Project , o resultado deve ser esse : 
Sep 19, 2012 4:38:12 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
INFO: Loaded JDBC driver: com.mysql.jdbc.Driver
Sep 19, 2012 4:38:14 PM org.springframework.jdbc.datasource.SingleConnectionDataSource initConnection
INFO: Established shared JDBC Connection: com.mysql.jdbc.JDBC4Connection@781f6226
id:1 nome: Cliente 1 Telefone:2222-3333
id:2 nome: Cliente 2 Telefone:4444-5555
BUILD SUCCESSFUL (total time: 3 seconds)
Figura 22 - Mostrando os resultados no NB

e aí estão os resultados. 
E assim concluímos nossa lição 04 (com uma implementação bem feia e simples, mas no passo 11 faremos isso de um jeito melhor).
Estrutura do projeto simples:
Figura 23 - Final da 1º Implementação - Quick and Dirty


Resumo : o que foi feito ?
- Criamos um banco no Mysql
- Configuramos uma conexão com um banco de dados utilizando jdbc através da classe org.springframework.jdbc.datasource.SingleConnectionDataSource;

 - Utilizamos a classe ContatoDAO extendendo a classe  org.springframework.jdbc.core.support.JdbcDaoSupport e implementando a classe org.springframework.jdbc.core.RowMapper   e vimos os métodos query do objeto JdbcTemplate (org.springframework.jdbc.core.JdbcTemplate).
- Com isso demos carga nos Objetos (Model)
- Apresentamos a lista de contatos

Download do Projeto NB 

Vamos melhorar esse projeto? Continue lendo....
11 - O exemplo acima explica algumas coisas, mas sua implementação no mundo real é inviável. Estou lendo alguns tutoriais que implementaram desse jeito como finaliza no passo 10.
Alguns problemas
  • A conexão não pode ser reutilizada
  • Precisamos distribuir as responsabilidades em classes e packages separados
  • Utilizei um Select *
  • A implementação com beans e a configuração no XML é muito mais limpa e eficiente
  • tem + , mas etc...
Vou dar uma sugestão de como separar melhor esse código. (OBS aos acadêmicos: estou compartilhando meus estudos com Spring, blz ?)

I) Vamos utilizar o gerenciador de Arquivos do seu Sistema Operacional p/ duplicar a pasta do projeto

Figura 24 - Duplicando o projeto

acrescente -v2 na nova pasta deixando ela com o nome SpringLesson04-v2
Figura 25 - Duplicando o projeto e corrigindo o nome

Fig 26 - Abrir o projeto





II) E no NB clique em Abrir Projeto e abra o Projeto SpringLesson04-v2
Figura 27 - Abrindo o projeto


III) Para evitar confusões vamos renomear esse projeto pelo NB

Figura 28 - Renomeando o projeto

Figura 29 - Renomeando o projeto

Com o Projeto renomeado, vamos ao passo 12.
A estrutura do projeto ficará assim após criarmos as novas classes :
Figura 30 - Estrutura Proposta


12) Vamos criar uma classe de conexão para que todos os DAOs possam utilizar a mesma conexão.
Crie uma nova Classe Conexao em um package springlesson04.db
Figura 31 - Classe Conexao prencha ClassName= Conexao, package=springlesson04.db

Arquivo Conexao.java
package springlesson04.db;

import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;


public class Conexao {

    private DataSource ds;
    private JdbcTemplate template;

    public Conexao() {
        this.ds = new SingleConnectionDataSource(
                "com.mysql.jdbc.Driver",
                "jdbc:mysql://ns1/springlessons",
                "springlessons",
                "DHADdSXcDF29WGXy",
                true);// se a conexao é fechada automaticamente
        this.template = new JdbcTemplate(ds);
    }

    public DataSource getDs() {
        return this.ds;
    }

    public JdbcTemplate getTemplate() {
        return this.template;
    }
}



13) Vamos criar um controller simples para o Contato

Figura 32 - Classe ContatoController prencha ClassName= ContatoController, package=springlesson04.controller

package springlesson04.controller;

import java.util.List;
import springlesson04.dao.ContatoDAO;
import springlesson04.model.Contato;

public class ContatoController {

    private ContatoDAO dao;

    public ContatoController(boolean daoOption) { // p/ instanciar o DAO apenas qdo preciso
        if (daoOption) {
            this.dao = new ContatoDAO();
        }
    }

    public List<Contato> getContatos() {
        List<Contato> lista = this.dao.listar();
        return lista;

    }

    public void mostrarContatos() {
        if (getContatos().isEmpty()) {
            System.out.println("Sem contatos cadastrados");
        } else {
            for (Contato c : getContatos()) {
                System.out.println("id:" + c.getId() + "\tnome: " + c.getNome() + "\tTelefone:" + c.getTelefone());
            }
        }

    }
}

14) vamos editar o ContatoDAO.java

package springlesson04.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import springlesson04.db.Conexao;
import springlesson04.model.Contato;

public class ContatoDAO extends JdbcDaoSupport {
    private JdbcTemplate t ;
    Conexao Con = new Conexao();

    public ContatoDAO() {
        setJdbcTemplate(Con.getTemplate());
        t = getJdbcTemplate(); 
    }

    public List<Contato> listar() {
        //JdbcTemplate t = getJdbcTemplate(); // o construtor esta fazendo isso
        try {
            List<Contato> listaContatos = t.query("SELECT `contato`.`id`,"
                    + "`contato`.`nome`,"
                    + "`contato`.`telefone`"
                    + "FROM `springlessons`.`contato`", new RowMapper() {
                @Override
                public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                    Contato C = new Contato();
                    C.setId(rs.getInt("id"));
                    C.setNome(rs.getString("nome"));
                    C.setTelefone(rs.getString("telefone"));
                    return C;

                }
            });
            return listaContatos;
        } catch (java.lang.NullPointerException npe) {
            System.out.println(npe.getMessage());
            return null;
        }
    }
}

15) Vamos editar o MainClass

package springlesson04;

import springlesson04.controller.ContatoController;

public class MainClass {

    private static ContatoController cc = new ContatoController(true);

    public static void main(String[] args) {

        mostrarContatosRegistrados();
    }

    private static void mostrarContatosRegistrados() {
        cc.mostrarContatos();
    }
}

isso já permite rodar o programa, clique em Run >> Project
Se funcionou, vamos fazer um teste, apague os registros do banco com um simples 

delete from springlessons.contato;

e rode o programa novamente veja se é executado sem erros.

16) Teste o recurso do NB de Ref/Encap
Figura 33 - Ref..
Figura 34 - Encap..

Agora o MainClass deve estar conforme a figura baixo, rode o programa de novo e veja se não tem erros :
 
package springlesson04;

import springlesson04.controller.ContatoController;

public class MainClass {

    private static ContatoController cc = new ContatoController(true);

    public static void main(String[] args) {

        mostrarContatosRegistrados();
    }

    private static void mostrarContatosRegistrados() {
        getCc().mostrarContatos();
    }

    public static ContatoController getCc() {
        return cc;
    }

    public static void setCc(ContatoController aCc) {
        cc = aCc;
    }
}


o resultado deve ser
Figurra 35 - 2º Compilação com sucesso, mas sem registros


e aí estão os resultados. Experimente rodar o script do INSERT novamente e rode o programa p/ ver o resultado

Figurra 36 - 3º Compilação com sucesso, com os  registros

E assim concluímos nossa lição 04 (com uma implementação mais elegante) .


Resumo : o que foi feito ?
- Criamos um controller simples ;
- Criamos um esquema p/ poder usar a Conexão em outras partes do sistema
- Adequamos os construtores p/ inicializarem o que for necessário
- Colocamos um Try / Catch na função listar do ContatoDAO , pois quando utilizamos as classes em modo static, apresentou erros de compilação

E vou continuar lendo antes de implementar Swing, p/ ver + dos recursos do Spring.

No próximo post , vamos adicionar Telas ao projeto.

Download do Projeto NB 


Dúvidas, Contribuições, Sugestões? Poste..
Grato,
Até a próxima.

Nenhum comentário: