Acessando banco de dados com Java
Esse é talvez um dos assuntos mais buscados por quem está aprendendo Java. Há muitas referências a isso na internet, inclusive uma série de artigos que o criado desse blog escreveu há mais de 5 anos atrás para o JavaFree, veja: Acessando dados com Java: 1º parte - Simples Dao - Acessando Dados com Java: Parte 2 - Prevendo problemas - Acessando Dados com Java: Parte 3 - Hibernate Annotations
Preparando o banco
O primeiro passo nosso é garantir que você tenha o MySQL instalado(que depende do sistema operacional sendo utilizado, Linux ou outros) e uma vez feito isso, entre no MySQL e então seguir alguns passos. Para esse artigo foi criado o seguinte:
- Usuário contas_app com senha aprendajavafx;
CREATE USER 'contas_app'@'localhost' IDENTIFIED BY 'aprendajavafx';
- Banco de dados contas crud-contas;
CREATE DATABASE `crud-contas` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci
- Garanta os privilégios do usuário contas_app para o banco crud-contas
mysql> use crud-contas
Database changed
mysql> GRANT ALL PRIVILEGES ON * . * TO 'contas_app'@'localhost';
- Tabela Contas com os campos que precisamos
create table contas(
id int auto_increment,
concessionaria varchar(30) not null,
descricao varchar(1000) not null,
data_vencimento date not null,
primary key(id)
);
Notem que o ID é auto_increment, ou seja, o MySQL vai dar o ID para nós. Se inserirmos alguns valores de teste, podemos notar que o ID já foi preenchido:
Criando uma classe para acesso ao banco de dados
Conforme falamos no artigo anterior, para trocar onde os dados serão armazenados nós iremos criar uma implementação de ContasService e trocar o tipo retornado no método getNewInstance.
Para falarmos com o nosso banco de dados MySQL, precisamos ter o Driver JDBC no classpath da aplicação, pois é ele quem possibilita a comunicação de uma aplicação Java com o banco. Por isso, baixe o driver JDBC do MySQL e coloque no classpath da aplicação.
A implementação do banco de dados simplesmente envia comandos SQL para o MySQL invés de abrir e manipular arquivos, assim temos que:
* Salvar significa realizar um INSERT com os dados da conta passada;
* Buscar é trazer dados usando SELECT e transformar em uma lista de contas;
* Apagar é realizar um DELETE;
* Por fim atualizar é a realização de um UPDATE.
Claro que tudo pode ser facilitado usando um framework que faz o mapeamento de objetos para o modelo relacional de banco de dados, como o Hibernate, mas por hoje vamos ficar no básico! Finalmente, veja como ficou nossa classe ContasDBService (lembre-se que todo o código pode ser encontrado no github):
A implementação do banco de dados simplesmente envia comandos SQL para o MySQL invés de abrir e manipular arquivos, assim temos que:
* Salvar significa realizar um INSERT com os dados da conta passada;
* Buscar é trazer dados usando SELECT e transformar em uma lista de contas;
* Apagar é realizar um DELETE;
* Por fim atualizar é a realização de um UPDATE.
Claro que tudo pode ser facilitado usando um framework que faz o mapeamento de objetos para o modelo relacional de banco de dados, como o Hibernate, mas por hoje vamos ficar no básico! Finalmente, veja como ficou nossa classe ContasDBService (lembre-se que todo o código pode ser encontrado no github):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.aprendendojavafx.crud.service.impl; | |
import java.sql.Connection; | |
import java.sql.DriverManager; | |
import java.sql.PreparedStatement; | |
import java.sql.ResultSet; | |
import java.sql.SQLException; | |
import java.text.ParseException; | |
import java.text.SimpleDateFormat; | |
import java.util.ArrayList; | |
import java.util.Date; | |
import java.util.List; | |
import org.aprendendojavafx.crud.model.Conta; | |
import org.aprendendojavafx.crud.service.ContasService; | |
/** | |
* Faz as operações de CRUD usando banco de dados MySQL. Para rodar essa classe | |
* vocë precisa <br /> | |
* - Certificar-se que o driver do MySQL está no classpath da aplicação - Criar | |
* o banco de dados e atualizar o código abaixo de acordo com o seu banco - | |
* Criar a tabela contas. | |
* | |
* Se houver qualquer erro, o programa irá sair, assim, cheque os logs para ver o erro. | |
* | |
* @author wsiqueir | |
* | |
*/ | |
public class ContasDBService implements ContasService { | |
// dados para acesso ao banco, atualize de acordo com o seu banco de dados | |
final String USUARIO = "contas_app"; | |
final String SENHA = "aprendajavafx"; | |
final String URL_BANCO = "jdbc:mysql://localhost:3306/crud-contas"; | |
// constantes de acesso | |
final String CLASSE_DRIVER = "com.mysql.jdbc.Driver"; | |
// comandos | |
final String INSERIR = "INSERT INTO contas(concessionaria, descricao, data_vencimento) VALUES(?, ?, STR_TO_DATE(?, '%d/%m/%Y'))"; | |
final String ATUALIZAR = "UPDATE contas SET concessionaria=?, descricao=?, data_vencimento = STR_TO_DATE(?, '%d/%m/%Y') WHERE id = ?"; | |
final String BUSCAR = "SELECT id, concessionaria, descricao, DATE_FORMAT(data_vencimento, %d/%m/%Y') FROM contas WHERE ID = ?"; | |
final String BUSCAR_TODOS = "SELECT id, concessionaria, descricao, DATE_FORMAT(data_vencimento, '%d/%m/%Y') FROM contas"; | |
final String APAGAR = "DELETE FROM contas WHERE id = ?"; | |
// tratamento de data | |
final String FORMATO_DATA = "dd/MM/yyyy"; | |
final SimpleDateFormat FORMATADOR = new SimpleDateFormat(FORMATO_DATA); | |
@Override | |
public void salvar(Conta conta) { | |
try { | |
Connection con = conexao(); | |
PreparedStatement salvar = con.prepareStatement(INSERIR); | |
String dateStr = FORMATADOR.format(conta.getDataVencimento()); | |
salvar.setString(1, conta.getConcessionaria()); | |
salvar.setString(2, conta.getDescricao()); | |
salvar.setString(3, dateStr); | |
salvar.executeUpdate(); | |
salvar.close(); | |
con.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
System.err.println("ERROR SALVANDO CONTA"); | |
System.exit(0); | |
} | |
} | |
@Override | |
public List<Conta> buscarTodas() { | |
List<Conta> contas = new ArrayList<>(); | |
try { | |
Connection con = conexao(); | |
PreparedStatement buscarTodos = con.prepareStatement(BUSCAR_TODOS); | |
ResultSet resultadoBusca = buscarTodos.executeQuery(); | |
while (resultadoBusca.next()) { | |
Conta conta = extraiConta(resultadoBusca); | |
contas.add(conta); | |
} | |
buscarTodos.close(); | |
con.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
System.err.println("ERROR BUSCANDO TODAS AS CONTAS."); | |
System.exit(0); | |
} | |
return contas; | |
} | |
@Override | |
public Conta buscaPorId(int id) { | |
Conta conta = null; | |
try { | |
Connection con = conexao(); | |
PreparedStatement buscar = con.prepareStatement(BUSCAR); | |
buscar.setInt(1, id); | |
ResultSet resultadoBusca = buscar.executeQuery(); | |
resultadoBusca.next(); | |
conta = extraiConta(resultadoBusca); | |
buscar.close(); | |
con.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
System.err.println("ERROR BUSCANDO CONTA COM ID " + id); | |
System.exit(0); | |
} | |
return conta; | |
} | |
@Override | |
public void apagar(int id) { | |
try { | |
Connection con = conexao(); | |
PreparedStatement apagar = con.prepareStatement(APAGAR); | |
apagar.setInt(1, id); | |
apagar.executeUpdate(); | |
apagar.close(); | |
con.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
System.err.println("ERROR APAGANDO CONTA COM ID " + id); | |
System.exit(0); | |
} | |
} | |
@Override | |
public void atualizar(Conta conta) { | |
try { | |
Connection con = conexao(); | |
PreparedStatement atualizar = con.prepareStatement(ATUALIZAR); | |
String dateStr = FORMATADOR.format(conta.getDataVencimento()); | |
atualizar.setString(1, conta.getConcessionaria()); | |
atualizar.setString(2, conta.getDescricao()); | |
atualizar.setString(3, dateStr); | |
atualizar.setInt(4, conta.getId()); | |
atualizar.executeUpdate(); | |
atualizar.close(); | |
con.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
System.err.println("ERROR ATUALIZANDO CONTA COM ID " + conta.getId()); | |
System.exit(0); | |
} | |
} | |
// abre uma nova conexão com o banco de dados. Se algum erro for lançado | |
// aqui, verifique o erro com atenção e se o banco está rodando | |
private Connection conexao() { | |
try { | |
Class.forName(CLASSE_DRIVER); | |
return DriverManager.getConnection(URL_BANCO, USUARIO, SENHA); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
if(e instanceof ClassNotFoundException) { | |
System.err.println("VERIFIQUE SE O DRIVER DO BANCO DE DADOS ESTÁ NO CLASSPATH"); | |
} else { | |
System.err.println("VERIFIQUE SE O BANCO ESTÁ RODANDO E SE OS DADOS DE CONEXÃO ESTÃO CORRETOS"); | |
} | |
System.exit(0); | |
// o sistema deverá sair antes de chegar aqui... | |
return null; | |
} | |
} | |
// extrain o objeto Conta do result set | |
private Conta extraiConta(ResultSet resultadoBusca) throws SQLException, ParseException { | |
Conta conta = new Conta(); | |
conta.setId(resultadoBusca.getInt(1)); | |
conta.setConcessionaria(resultadoBusca.getString(2)); | |
conta.setDescricao(resultadoBusca.getString(3)); | |
Date dataVencimento = FORMATADOR.parse(resultadoBusca.getString(4)); | |
conta.setDataVencimento(dataVencimento); | |
return conta; | |
} | |
} |
Boa tarde, tenho muito interesse em aprender javafx conheço um pouco sobre java e em uma googlada encontrei este blog, por onde devo começar? Forte abraço!
ResponderExcluirOlá! Comece por aqui -> http://aprendendo-javafx.blogspot.com.br/p/o-que-e-javafx.html
ExcluirBons Estudos :)
Boa noite, estou com uma dúvida, realizei o CRUD utilizando o banco de dados, como eu incluo a ação do botão salvar sendo que utilizo javafx FXML, utilizo o SceneBuilder para criar minhas telas, nessa parte do código não ficou claro como realizo essa operação, caso possa me ajudar, serei grato.
ResponderExcluirAbraços.
Este comentário foi removido pelo autor.
ResponderExcluirBom dia,
ResponderExcluirEstou com o seguinte problema em relação a data, no meu banco de dados MySql, a data está correta, quando exibo as informações em uma TableView, a data está vindo sempre com 1 dia a menos. Por exemplo: no banco esta: 12/09/2018, na TableView aparece 11/09/2018, o que pode estar ocasionando esse erro?
Estou usando o Eclipse Oxygen, desde já agradeço