ProjetoDb1b

1. Criar o projeto ProjetoDb1b no netbeans:

Arquivo > Novo projeto ... > aplicativo java > Próximo  > Nome do projeto: ProjetoDb1b > Finalizar

Não marcar Criar classe principal

2. Criação do banco de dados programador no phpMyAdmin


3. Criação da tabela contatos.sql  no phpMyAdmin


3.1. Estrutura da tabela contatos


3.2. Visualização da tabela contatos


4. Apresentação do projeto já feito

Este projeto foi feito no Netbeans, o mesmo é dividido em seis arquivos (classes) pode ser observado na figura abaixo sua estrutura e seu layout, foi utilizado apenas o modo texto, ou seja, a parte gráfica (botões, labeis, caixas de textos e a janela) foram criados usando o código java puro, no próximo projeto será feito este mesmo projeto usando o modo gráfico do Netbeans (clicar e arrastar os botões). Para aprender os conceitos e funcionalidade é preferível começar pelo código puro. Como pode ser observado, este projeto é capaz de salvar, alterar e excluir campos da tabela bem como localizar registro da tabela pesquisado pelo nome. Ainda possui os botões de navegabilidade.

É indispensável para o entendimento deste tutorial a compreensão do tutorial Banco de Dados

5. Foi criado o projeto ProjetoDb1b, sem classe principal: Menu Arquivo > Novo projeto... > Aplicativo Java > Próximo

6. Foi criado o pacote controle: um clique com o botão direito em Pacotes de código-fonte > Novo > Pacote Java > Nome do Pacote.

6.1. Foi criado a classe ContatoController.java dentro do pacote controle:

Um clique com o botão direiro no pacote contro > Novo > Classe Java > Nome da classe

6.2. Comentário sobre a classe ContatoController.java

6.2.1. Uso de data

7. Foi criado o pacote dao e dentro dele a classe ConnectionDataBase.java, a classe ContatoDao.java  e a classe GenericDao.java.

8. Foi criado o pacote frame e dentro dele a classe ContatoFrame.java.

9. Foi criado o pacote model e dentro dele a classe Contato.java.

10. Foi inserido a bliblioteca MySQL JDBC Drive, para isso dê um clique com o otão direito na pasta Biblioteca, clique em Adicionar biblioteca..., escolha o drive para o MySQL.

11. Código Fonte do ProjetoDb1b:

11.1. Pacote controle

ContatoController.java

package controle;

import dao.ContatoDao;
import model.Contato;
import javax.swing.*;
import java.sql.Date;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

public class ContatoController {

    private Date formatarData(String data) throws ParseException {
        DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
        return new Date(formatter.parse(data).getTime());
    }

    public void salvar(String nome, String apelido, String dtNascimento) throws
            SQLException, ParseException {
        Contato contato = new Contato();
        contato.setNome(nome);
        contato.setApelido(apelido);
        contato.setDtNascimento(formatarData(dtNascimento));
        new ContatoDao().salvar(contato);
    }

    public void alterar(long id, String nome, String apelido, String dtNascimento) throws ParseException, SQLException {
        Contato contato = new Contato();
        contato.setId(id);
        contato.setNome(nome);
        contato.setApelido(apelido);
        contato.setDtNascimento(formatarData(dtNascimento));
        new ContatoDao().alterar(contato);
    }

    public List<Contato> listaContatos() {
        ContatoDao dao = new ContatoDao();
        try {
            return dao.findContatos();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "Problemas ao localizar contato\n" + e.getLocalizedMessage());
        }
        return null;
    }

    public void excluir(long id) throws SQLException {
        new ContatoDao().excluir(id);
    }

    public Contato buscaContatoPorNome(String nome) throws SQLException {
        ContatoDao dao = new ContatoDao();
        return dao.findByName(nome);
    }
}

Variaveis do tipo String e primitivas não necessitam de new, variáveis dos outros tipos necessintam de new para criar uma instância, como é o caso de variáveis do tipo Date. O método formatarData( ) recebe como argumento um String e retorno é do tipo Date, o objeto formatter formata a data.

A classe ContatoController faz a comunicação entre o banco de dados e a interface, utiliza-se o modelo conhecido como MVC(Model View Controller), onde separa-se as regras de negócios e interface. Há um método para manipular a data. Os métodos desta classe serão chamados pela interface, e farão a chamada aos métodos das classes dao’s para então retornar para a interface o resultado.

10.2. Pacote dao
10.2.1. Criar a classe de conexão

ConnectionDataBase.java

package dao;

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

public class ConnectionDataBase {

    private static final String URL_MYSQL = "jdbc:mysql://localhost:3306/programador";
    private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
    private static final String USER = "root";
    private static final String PASS = "";

//VARIÁVEIS GLOBAIS PARA CONEXÃO COM O BANCO DE DADOS MYSQL.
//final = constante, nao podem ser alteradas
//private = privado, so podem ser acessadas por métodos da mesma classe


    public static Connection getConnection() {
        System.out.println("Conectando ao Banco de Dados");
        try {
            Class.forName(DRIVER_CLASS);
            return DriverManager.getConnection(URL_MYSQL, USER, PASS);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return null;
    }
}

Observe que o usuário do WampServer é “root” e a senha é vazia por padrão. Quem utilizou outra instalação do Mysql, deve alterar para seu usuário e sua senha.

Foi criado o método getConnection() que retorna um objeto de conexão com o banco de dados.
Neste método é chamado o método estático getConnection(...) da classe DriverMenager, pelo qual passou-se as configurações para a conexão.

Quando se precisa de uma conexão com o banco de dados, apenas faz-se uma chamada ao método criado. Esta classe poderá ser utilizada com qualquer banco de dados, basta apenas alterar os parâmetros DRIVER_CLASS, URL_MYSQL, USER  PASS e adicionar no projeto o driver JDBC referente ao banco de dados usado.

10.2.2. Classe ContatoDao.java

ContatoDao.java

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ContatoDao extends GenericDao {

    public void salvar(Contato contato) throws SQLException {
        String insert = "INSERT INTO contatos(nome, apelido, data_nascimento) VALUES(?,?,?)";
        save(insert, contato.getNome(), contato.getApelido(), contato.getDtNascimento());
    }

    public void alterar(Contato contato) throws SQLException {
        String update = "UPDATE CONTATOS " + "SET nome = ?, apelido = ?, data_nascimento = ? " + "WHERE id = ?";
        update(update, contato.getId(), contato.getNome(), contato.getApelido(),
GenericDao                 contato.getDtNascimento());
    }

    public void excluir(long id) throws SQLException {
        String delete = "DELETE FROM CONTATOS WHERE id = ?";
        delete(delete, id);
    }

    public List<Contato> findContatos() throws SQLException {
        List<Contato> contatos = new ArrayList<Contato>();
        String select = "SELECT * FROM CONTATOS";
        PreparedStatement stmt = getConnection().prepareStatement(select);
        ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
            Contato contato = new Contato();
            contato.setId(rs.getLong("id"));
            contato.setNome(rs.getString("nome"));
            contato.setApelido(rs.getString("apelido"));
            contato.setDtNascimento(rs.getDate("data_nascimento"));
            contatos.add(contato);
        }
        rs.close();
        stmt.close();
        return contatos;
    }

    public Contato findByName(String nome) throws SQLException {
        String select = "SELECT * FROM CONTATOS WHERE nome = ?";
        Contato contato = null;
        PreparedStatement stmt = getConnection().prepareStatement(select);
        stmt.setString(1, nome);
        ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
            contato = new Contato();
            contato.setId(rs.getLong("id"));
            contato.setNome(rs.getString("nome"));
            contato.setApelido(rs.getString("apelido"));
            contato.setDtNascimento(rs.getDate("data_nascimento"));
        }
        rs.close();
        stmt.close();
        return contato;
    }
}

Foi utilizado uma herança nesta classe, herdando os métodos criados na classe GenericDao. Os métodos salvar(), alterar() e excluir() possuem a criação do SQL que será executado no banco de dados e uma chamada ao método da classe GenericDao, passando para ele o SQL e os demais parâmetros.
Os métodos salvar(), alterar() e excluir(), serão os métodos acessados pela classe ContatoController para manipulação com o banco de dados. Os outros dois métodos, um que retorna através de um select uma lista com todos os contatos cadastrados no banco de dados e um que realizara um select pela coluna nome da tabela contato do banco de dados.

10.2..3. Classe GenericDao.java

GenericDao.java

package dao;

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

public abstract class GenericDao {

    private Connection connection;

    protected GenericDao() { /*
         * é o construtor da classe GenericDao configurado para executar o
         * metodo getConnection() na sua inicialização
         */
        this.connection = ConnectionDataBase.getConnection();
    }

    protected Connection getConnection() {  /*
         * sobrescrita do método getConnection() para retornar a conexão
         */
        return connection;
    }

    protected void save(String insertSql, Object... parametros) throws
            SQLException {
        PreparedStatement pstmt = getConnection().prepareStatement(insertSql);
        for (int i = 0; i < parametros.length; i++) {
            pstmt.setObject(i + 1, parametros[i]);
        }
        pstmt.execute();
        pstmt.close();
    }

    protected void update(String updateSql, Object id, Object... parametros)
            throws SQLException {
        PreparedStatement pstmt = getConnection().prepareStatement(updateSql);
        for (int i = 0; i < parametros.length; i++) {
            pstmt.setObject(i + 1, parametros[i]);
        }
        pstmt.setObject(parametros.length + 1, id);
        pstmt.execute();
        pstmt.close();
    }

Esta classe poderá ser usada por qualquer outra classe que faça acesso ao banco de dados. A vantagem de criar uma classe desse tipo é que não precisa criar estes três métodos em cada classe que os utiliza, precisa-se apenas passar os parâmetros necessários para as ações com o banco de dados.

Cria-se um atributo connection, do tipo Connection, que recebe através do construtor da classe uma conexão com o banco de dados sempre que a classe dao for instanciada. Essa conexão recebida vem como retorno da classe ConnectionDataBase.

Os métodos são protected para que apenas as classes que herdam GenericDao possoam ter acesso a eles.

O método save() recebe dois parametros, o primeiro é o sql que contém o insert e o segundo é uma lista de argumentos que pode passar vários parâmetros de uma só vez, algo muito parecido com um array, que conterá o valor dos campos do insert. O métod  update() possui um parâmetro a mais, que será o id da coluna que iremos executar o update.

10.3. Pacote frame: classe ContatoFrame.java

ContatoFrame.java

package frame;

import controle.ContatoController;
import model.Contato;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

public class ContatoFrame extends JFrame {

    private JLabel lbNome, lbApelido, lbDtNascimento;
    private JTextField txtNome, txtApelido, txtDtNascimento, txtLocalizar;
    private JButton btnSalvar, btnAlterar, btnExcluir, btnClear, btnLocalizar;
    private JButton btnPrimeiro, btnProximo, btnAnterior, btnUltimo;
    private List<Contato> contatoList = new ContatoController().listaContatos();
    private int registroAtual = 0;

    public ContatoFrame() {
        super("Contatos");
        Container tela = getContentPane();
        setLayout(null);
        lbNome = new JLabel("Nome");
        lbApelido = new JLabel("Apelido");
        lbDtNascimento = new JLabel("Data de Nascimento(dd/mm/aaaa)");
        lbNome.setBounds(10, 10, 240, 15);
        lbApelido.setBounds(10, 50, 240, 15);
        lbDtNascimento.setBounds(10, 90, 240, 15);
        lbNome.setForeground(Color.BLACK);
        lbApelido.setForeground(Color.BLACK);
        lbDtNascimento.setForeground(Color.BLACK);
        lbNome.setFont(new Font("Courier New", Font.BOLD, 14));
        lbApelido.setFont(new Font("Courier New", Font.BOLD, 14));
        lbDtNascimento.setFont(new Font("Courier New", Font.BOLD, 14));
        tela.add(lbNome);
        tela.add(lbApelido);
        tela.add(lbDtNascimento);
        txtNome = new JTextField();
        txtApelido = new JTextField();
        txtDtNascimento = new JTextField();
        txtNome.setBounds(10, 25, 265, 20);
        txtApelido.setBounds(10, 65, 265, 20);
        txtDtNascimento.setBounds(10, 105, 265, 20);
        tela.add(txtNome);
        tela.add(txtApelido);
        tela.add(txtDtNascimento);
        btnSalvar = new JButton("Salvar");
        btnAlterar = new JButton("Alterar");
        btnExcluir = new JButton("Excluir");
        btnClear = new JButton("Limpar");
        btnPrimeiro = new JButton("|<");
        btnAnterior = new JButton("<<");
        btnProximo = new JButton(">>");
        btnUltimo = new JButton(">|");
        btnSalvar.setBounds(280, 25, 80, 20);
        btnAlterar.setBounds(280, 65, 80, 20);
        btnExcluir.setBounds(280, 105, 80, 20);
        tela.add(btnSalvar);
        tela.add(btnAlterar);
        tela.add(btnExcluir);
        btnPrimeiro.setBounds(10, 135, 50, 20);
        btnAnterior.setBounds(60, 135, 50, 20);
        btnClear.setBounds(110, 135, 75, 20);
        btnProximo.setBounds(185, 135, 50, 20);
        btnUltimo.setBounds(235, 135, 50, 20);
        tela.add(btnPrimeiro);
        tela.add(btnAnterior);
        tela.add(btnClear);
        tela.add(btnProximo);
        tela.add(btnUltimo);
        JLabel lbLocalizar = new JLabel("Localizar por nome");
        lbLocalizar.setBounds(10, 160, 220, 20);
        txtLocalizar = new JTextField();
        txtLocalizar.setBounds(10, 180, 220, 20);
        btnLocalizar = new JButton("Ir");
        btnLocalizar.setBounds(230, 180, 55, 20);
        tela.add(lbLocalizar);
        tela.add(txtLocalizar);
        tela.add(btnLocalizar);
        setSize(400, 250);
        setVisible(true);
        setLocationRelativeTo(null);
        btnSalvar.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickSalvar();
                    }
                });
        btnAlterar.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickAlterar();
                    }
                });
        btnExcluir.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickExcluir();
                    }
                });
        btnClear.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        clearFields();
                        registroAtual = 0;
                    }
                });
        btnLocalizar.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickLocalizar();
                    }
                });
        btnPrimeiro.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickPrimeiro();
                    }
                });
        btnAnterior.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickAnterior();
                    }
                });
        btnProximo.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickProximo();
                    }
                });
        btnUltimo.addActionListener(
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        onClickUltimo();
                    }
                });
    }

    private void onClickUltimo() {
        registroAtual = contatoList.size() - 1;
        getValores(registroAtual);
    }

    private void onClickProximo() {
        if (registroAtual != contatoList.size() - 1) {
            getValores(++registroAtual);
        }
    }

    private void onClickAnterior() {
        if (registroAtual != 0) {
            getValores(--registroAtual);
        }
    }

    private void onClickPrimeiro() {
        registroAtual = 0;
        getValores(registroAtual);
    }

    private void getValores(int index) {
        if (index <= contatoList.size() - 1) {
            Contato contatoAtual = contatoList.get(index);
            txtNome.setText(contatoAtual.getNome());
            txtApelido.setText(contatoAtual.getApelido());
            txtDtNascimento.setText(new SimpleDateFormat("dd/MM/yyyy").format(contatoAtual.getDtNascimento()));
        }
    }

    private void onClickAlterar() {
        ContatoController cc = new ContatoController();
        long id = contatoList.get(registroAtual).getId();
        try {
            cc.alterar(id, txtNome.getText(), txtApelido.getText(),
                    txtDtNascimento.getText());
            JOptionPane.showMessageDialog(this, "Contato alterado com sucesso!");
            clearFields();
            contatoList = new ContatoController().listaContatos();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(this, "Nao foi possivel alterar contato!\n" + e.getLocalizedMessage());
        } catch (ParseException e) {
            JOptionPane.showMessageDialog(this, "Data possui formato inválido!\n"
                    + e.getLocalizedMessage());
        }
    }

    private void onClickSalvar() {
        ContatoController cc = new ContatoController();
        try {
            cc.salvar(txtNome.getText(), txtApelido.getText(),
                    txtDtNascimento.getText());
            JOptionPane.showMessageDialog(this, "Contato salvo com sucesso!");
            clearFields();
            contatoList = new ContatoController().listaContatos();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(this, "Nao foi possivel salvar contato!\n" + e.getLocalizedMessage());
        } catch (ParseException e) {
            JOptionPane.showMessageDialog(this, "Data possui formato inválido!\n"
                    + e.getLocalizedMessage());
        }
    }

    private void onClickExcluir() {
        ContatoController cc = new ContatoController();
        long id = contatoList.get(registroAtual).getId();
        try {
            cc.excluir(id);
            JOptionPane.showMessageDialog(this, "Contato excluido com sucesso!");
            clearFields();
            contatoList = new ContatoController().listaContatos();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(this, "Nao foi possivel excluir o contato!\n" + e.getLocalizedMessage());
        }
    }

    private void onClickLocalizar() {
        ContatoController cc = new ContatoController();
        try {
            Contato c = cc.buscaContatoPorNome(txtLocalizar.getText());
            txtNome.setText(c.getNome());
            txtApelido.setText(c.getApelido());
            txtDtNascimento.setText(new SimpleDateFormat("dd/MM/yyyy").format(c.getDtNascimento()));
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(this, "Ocorreu um erro, tente novamente!\n" + e.getLocalizedMessage());
        } catch (NullPointerException e) {
            JOptionPane.showMessageDialog(this, "Contato não localizdo ou não existe!\n" + e.getLocalizedMessage());
        }
    }

    private void clearFields() {
        txtNome.setText("");
        txtApelido.setText("");
        txtDtNascimento.setText("");
        txtLocalizar.setText("");
    }

    public static void main(String[] args) {
        ContatoFrame frame = new ContatoFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}


10.4. Pacote model: classe Contato.java

Nesta classe tem-se a criação da interface com usuário e os métodos que se comunicam com o controller para enviar ou receber os dados do banco de dados. Além dos atributos referentes aos componentes da interface, foram criados mais dois atributos, o contatoList e o registroAtual. O contatoList é uma lista que irá guarda a consulta do banco de dados para a visualização de todos os contatos cadastrados. O registroAtual irá guardar a posição atual do regitro na lista, que será útil para a navegação entre os registros.

Os métodos onClickUltimo(), onClickProximo(), onClickAnterior() e onClickPrimeiro() enviarão para o método getValores() a posição atual na lista, para então os campos do formulário serem preenchidos com estes valores. Esta navegação é feita toda dentro da lista, assim poupa o trabalho de ficar abrindo e fechando a conexão com o banco de dados a todo momento, o que é considerado um alto custo para uma apliação.
Os métodos onClickSalvar(), onClickExcluir() e onClickAlterar(), passam por parâmetros os dados necessários para os métodos no controller interagirem com o banco de dados.

O método onClickLocalizar() irá fazer uma consulta através do parâmetro nome. O parâmetro deve ser digitado no campo especifico e o clique no botão “Ir“ faz a chamada ao método onClickLocalizar() que se comunica com o controller. O controller faz a chamada aos dao’s que retorna o resultado da consuta.

O método clearFields() serve apenas para limpar os campos quando estiverem preenchidos com dados.

Sobre a utilização do padrão MVC, por exemplo, no método onClickSalvar() poderia ao invés de enviar 3 parâmetros do tipo String, um unico parâmetro do tipo Contato. Assim, ao invés de criar o objeto contato no controller como foi feito, criariamos dentro do método onClickSalvar().

Contato.java

package model;

import java.sql.Date;

public class Contato {

    private Long id;
    private String nome;
    private String apelido;
    private Date dtNascimento;
//gere os métodos getters and setters

    public String getApelido() {
        return apelido;
    }

    public void setApelido(String apelido) {
        this.apelido = apelido;
    }

    public Date getDtNascimento() {
        return dtNascimento;
    }

    public void setDtNascimento(Date dtNascimento) {
        this.dtNascimento = dtNascimento;
    }

    public Long getId() {
        return id;
    }

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

    public String getNome() {
        return nome;
    }

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

A classe contato terá como atributos os campos da tabela Contato. Ela foi criada no pacote model, esse model não é o mesmo Model do padrão MVC, é um pacote onde se costuma colocar as classes de entidades.


Basta selecionar e copia o código pelo próprio Browser.
ContatoController.txt
ConnectionDataBase.txt
ContatoDao.txt
GenericDao.txt
ContatoFrame.txt
Contato.txt