Aprenda Java com Banco de Dados

  • Página Inicial
  • Contato!
  • Tudo sobre Java com Banco de Dados Parte 1!
  • Tudo sobre Java com Banco de Dados Parte 2!
  • Tudo sobre Java com Banco de Dados Parte 3!
  • Tudo sobre Java com Banco de Dados Parte 4!
  • Tudo sobre Java com Banco de Dados Parte 5!
  • Tudo sobre Java com Banco de Dados Parte 6!
  • Tudo sobre Java com Banco de Dados Parte 7!
  • Tudo sobre Java com Banco de Dados Parte 3

    Consulta - FK Chave Estrangeira usando Composição

    No banco de dados, podemos fazer a consulta simplesmente dando select * from produto as p inner join categoria as c on c.id = p.categoria_id, para comparação.

    Caso queira renomear alguma coluna por ter nome igual, podemos "renomear" também com o as.

    Coloque em ProdutoDAO esse método de consulta:

    
    public List<Produto> findAll() { // Importe java.util.List
        String sql = "select p.id as pid, p.descricao as pdesc, qtd, valor, categoria_id, c.id as cid, c.descricao as cdesc from produto p inner join categoria c on c.id = p.categoria_id";
    
        PreparedStatement stmt = null;
        ResultSet rs = null; // Importe java.sql.ResultSet
    
        List<Produto> produtos = new ArrayList<>(); // Importe java.util.ArrayList
    
        try {
            stmt = con.prepareStatement(sql);
            rs = stmt.executeQuery(); // Isso executa a query no banco.
    
            while(rs.next()) { // Executa enquanto os dados forem true.
                Produto prod = new Produto();
    
                prod.setId(rs.getInt("pid"));
                prod.setDescricao(rs.getString("pdesc"));
                prod.setQtd(rs.getInt("qtd"));
                prod.setValor(rs.getDouble("valor"));
    
                Categoria cate = new Categoria(); // Importe
                cate.setId(rs.getInt("cid"));
                cate.setDescricao(rs.getString("cdesc"));
    
                prod.setCate(cate);
    
                produtos.add(prod);
            }
        }
        catch(SQLException ex) {
            System.err.println("ERRO: " + ex);
        }
        finally {
            ConnectionFactory.closeConnection(con, stmt, rs);
        }
    
        return produtos;
    }
    
    

    Agora em ProdutoDAOTest, faça isso (coloque um @Ignore no método inserir antes):

    
    @Test
    public void listar() throws SQLException {
        ProdutoDAO dao = new ProdutoDAO();
    
        for(Produto p: dao.findAll()) {
            System.out.print("Descrição Produto: " + p.getDescricao());
            System.out.print(" - ");
            System.out.println("Descrição Categoria: " + p.getCate().getDescricao());
        }
    }
    
    

    Melhorando DAO com View MySQL

    Para isso, basta no SQL colocar esse comando assim:

    
    create view vw_produtocategoria as select p.id as pid, p.descricao as pdesc, qtd, valor, categoria_id, c.id as cid, c.descricao as cdesc from produto p inner join categoria c on c.id = p.categoria_id;
    
    

    Dessa forma, a consulta pode ser feita simplesmente dando select * from vw_produtocategoria.

    No método findAll em ProdutoDAO, basta substituir a SQL por isso aí acima. Depois é só executar o test.

    Atualizar Registro com Composição

    Em ProdutoDAO, adicione um método dessa forma:

    
    public boolean update(Produto prod) { // Importar model.bean.Produto
        String sql = "update produto set descricao = ?, qtd = ?, valor = ?, categoria_id = ? where id = ?";
    
        PreparedStatement stmt = null; // Importar;
        
        try {
            stmt = con.prepareStatement(sql);
            stmt.setString(1, prod.getDescricao());
            stmt.setInt(2, prod.getQtd());
            stmt.setDouble(3, prod.getValor());
            stmt.setInt(4, prod.getCate().getId()); // Aqui pega o inteiro que está dentro da classe Categoria
            stmt.setInt(5, prod.getId());
            stmt.executeUpdate(); // Isso é responsável pelo insert, update e delete no banco.
    
            return true;
        }
        catch(SQLException ex) {
            System.err.println("Erro: " + ex);
    
            return false;
        }
        finally { // Isso fecha a conexão
            ConnectionFactory.closeConnection(con, stmt);
        }
    }
    
    

    No ProdutoDAOTest, podemos usar um @Ignore do listar(), e coloque esse método abaixo dele:

    
    @Test
    public void atualizar() {
        Categoria cate = new Categoria(); // Importe
        cate.setId(1);
    
        Produto prod = new Produto(); // Importe
    
        prod.setDescricao("Farinha");
        prod.setQtd(20);
        prod.setValor(10);
        prod.setCate(cate); // Aqui passamos o objeto
        prod.setId(3);
    
        ProdutoDAO dao = new ProdutoDAO();
    
        if(dao.update(prod)) {
            System.out.println("Salvo com Sucesso!");
        }
        else {
            fail("Erro ao Salvar!");
        }
    }
    
    

    Deletar Registro com Composição

    Coloque isso em ProdutoDAO:

    
    public boolean delete(Produto prod) { // Importar model.bean.Categoria
        String sql = "delete from produto where id = ?";
    
        PreparedStatement stmt = null; // Importar;
    
        try {
            stmt = con.prepareStatement(sql);
            stmt.setInt(1, prod.getId()); // Substituir pela id desejada
            stmt.executeUpdate(); // Isso é responsável pelo insert, update e delete no banco.
    
            return true;
        }
        catch(SQLException ex) {
            System.err.println("Erro: " + ex);
    
            return false;
        }
        finally { // Isso fecha a conexão
            ConnectionFactory.closeConnection(con, stmt);
        }
    }
    
    

    E no ProdutoDAOTest, coloque isso:

    
    @Test
    public void deletar() {
        Produto prod = new Produto();
        prod.setId(3);
        ProdutoDAO dao = new ProdutoDAO();
    
        if(dao.delete(prod)) {
            System.out.println("Deletado com Sucesso!");
        }
        else {
            fail("Erro ao Deletar!");
        }
    }
    
    

    Organizando Projeto no Netbeans

    Para prosseguirmos, vamos usar interfaces gráficas para o Java.

    Crie um novo projeto Java e crie o pacote view, crie também os pacotes connection, model.bean e model.dao.

    Crie um frame com o nome ViewJTable, centralize, coloque o título e tudo mais, e nele crie um painel e cubra até um pouco menos da metade superior, nele coloque os labels e os campos para descrição, quantidade e preço, e um botão para cadastrar (variáveis dos campos serão txtDesc, txtQtd e txtPrec, e do botão será btnCadr).

    Crie um painel na parte de baixo e coloque uma tabela (variável paneProds) dentro dele e a redimensione, clique nela e com o botão direito, vá em conteúdo da tabela e em colunas, edite os nomes para Descrição, Quantidade e Preço (mantenha os tipos em Object, pois trabalharemos com objetos), tire a opção editável e exclua as colunas extras. No mesmo local, em linhas, exclua todas.

    PS: As tabelas já são incluídas com um painel de rolagem, não sendo necessário colocar outra.

    No action performed do Cadastrar, coloque esse código:

    
    private void btnCadrActionPerformed(java.awt.event.ActionEvent evt) {                                        
        if(!txtDesc.getText().trim().equals("") && !txtQtd.getText().trim().equals("") && !txtPrec.getText().trim().equals("")) {
            DefaultTableModel dtmProds = (DefaultTableModel)paneProds.getModel(); // Isso pega o modelo da tabela, importe javax.swing.table.DefaultTableModel
    
            Object dados[] = {txtDesc.getText().trim(), txtQtd.getText().trim(), txtPrec.getText().trim()}; // Isso pega os dados dos campos.
    
            dtmProds.addRow(dados); // Isso envia os dados pra tabela.
            
            // Essas linhas apagam os dados escritos nos campos:
                
            txtDesc.setText("");
            txtQtd.setText("");
            txtPrec.setText("");
        }
        else {
            JOptionPane.showMessageDialog(null, "Preencha todos os campos!", "Aviso", JOptionPane.WARNING_MESSAGE); // Importe javax.swing.JOptionPane
        }     
    }
    
    

    No pacote model.bean, crie a classe Produtos e coloque esses dados para fazer a conexão:

    
    package model.bean;
    
    public class Produto {
        private int id;
        private String descricao;
        private int qtd;
        private double preco;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getDescricao() {
            return descricao;
        }
    
        public void setDescricao(String descricao) {
            this.descricao = descricao;
        }
    
        public int getQtd() {
            return qtd;
        }
    
        public void setQtd(int qtd) {
            this.qtd = qtd;
        }
    
        public double getPreco() {
            return preco;
        }
    
        public void setPreco(double preco) {
            this.preco = preco;
        }
    }
    
    

    Criando ConnectionFactory

    Primeiro, no MySQL, crie o banco de dados assim:

    
    create database dbmercadinho
    default character set utf8
    default collate utf8_general_ci;
    
    use dbmercadinho;
    
    create table produto (
        id int not null auto_increment,
        descricao varchar(50) unique,
        qtd int not null,
        preco decimal not null,
        primary key(id)
    )
    default charset = utf8;
    
    

    Vá em bibliotecas e adicione a biblioteca do Driver JDBC do MySQL, no projeto Java.

    Para criar a conexão, crie uma classe Java com o nome ConnectionFactory, no pacote connection, com esse código:

    
    package connection;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class ConnectionFactory {
        private static final String DRIVER = "com.mysql.jdbc.Driver";
        private static final String URL = "jdbc:mysql://localhost:3306/dbmercadinho";
        private static final String USER = "root";
        private static final String PASS = "";
        
        public static Connection getConnection() {
            try {
                return DriverManager.getConnection(URL, USER, PASS);
            }
            catch(SQLException ex) {
                throw new RuntimeException("Erro na Conexão!", ex);
            }
        }
        
        public static void closeConnection(Connection con) {
            try {
                if(con != null) {
                    con.close();
                }
            }
            catch(SQLException ex) {
                Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        public static void closeConnection(Connection con, PreparedStatement stmt) {
            closeConnection(con);
            
            try {
                if(stmt != null) {
                    stmt.close();
                }
            }
            catch(SQLException ex) {
                Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        public static void closeConnection(Connection con, PreparedStatement stmt, ResultSet rs) {
            closeConnection(con, stmt);
            
            try {
                if(rs != null) {
                    rs.close();
                }
            }
            catch(SQLException ex) {
                Logger.getLogger(ConnectionFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
        }  
    }
    
    

    Caso esteja usando o PostgreSQL, adicione a biblioteca do Driver JDBC do PostgreSQL, e faça a ligação assim:

    
    private static final String DRIVER = "org.postgresql.jdbc";
    private static final String URL = "jdbc:postgresql://localhost:5432/dbmercadinho";
    private static final String USER = "postgres";
    private static final String PASS = "admin"; // Senha configurada
    
    

    Criado DAO e Salvando Dados

    No pacote model.dao, crie a classe ProdutoDAO, e coloque esse código:

    
    package model.dao;
    
    import connection.ConnectionFactory;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import javax.swing.JOptionPane;
    import model.bean.Produto;
    
    public class ProdutoDAO {
        private Connection con = null; // Importar java.sql.Connection
        
        public ProdutoDAO() {
            con = ConnectionFactory.getConnection(); // Importar connection.ConnectionFactory
        }
    
        public void create(Produto p) {
            PreparedStatement stmt = null;
            String sql = "insert into produto (descricao, qtd, preco) values (?, ?, ?)"; // Inserir os dados do MySQL.
            
            try {
                stmt = con.prepareStatement(sql);
                stmt.setString(1, p.getDescricao());
                stmt.setInt(2, p.getQtd());
                stmt.setDouble(3, p.getPreco());
                
                stmt.executeUpdate();
                
                JOptionPane.showMessageDialog(null, "Salvo com Sucesso!", "Informação", JOptionPane.INFORMATION_MESSAGE);
            }
            catch(SQLException ex) {
                JOptionPane.showMessageDialog(null, "Erro ao Salvar!\n\n" + ex, "Erro", JOptionPane.ERROR_MESSAGE);
            }
            finally {
                ConnectionFactory.closeConnection(con, stmt);
            }
        }
    }
    
    

    No frame ViewJTable, no action do botão Cadastrar, altere o código dessa forma:

    
    private void btnCadActionPerformed(java.awt.event.ActionEvent evt) {                                       
        if(!txtDesc.getText().trim().equals("") && !txtQtd.getText().trim().equals("") && !txtPrec.getText().trim().equals("")) {
            Produto p = new Produto(); // Importe
            ProdutoDAO dao = new ProdutoDAO(); // Importe
    
            p.setDescricao(txtDesc.getText().trim());
            p.setQtd(Integer.parseInt(txtQtd.getText().trim()));
            p.setPreco(Double.parseDouble(txtPrec.getText().replace(",", ".").trim()));
    
            dao.create(p);
    
            // Isso limpa os campos:
    
            txtDesc.setText("");
            txtQtd.setText("");
            txtPrec.setText("");
        }
        else {
            JOptionPane.showMessageDialog(null, "Preencha todos os Campos!", "Aviso!", JOptionPane.WARNING_MESSAGE);
        }      
    }
    
    

    PS: Esse código pode ser colocado dentro de um método de checkagem de login e sendo chamado no evento através da função, isso é possível fazer com a maioria desses códigos.