JDBC (Fundamentos)

Propaganda
JDBC (Fundamentos)
Sang Shin
Java Technology Architect
Sun Microsystems, Inc.
[email protected]
www.javapassion.com
1
Agenda
•
•
•
•
•
O que é JDBC?
Passo a passo do uso da API JDBC
DataSource & pool de Conexões
Transações
Prepared and Callable Statements
2
O que é JDBC?
3
O que é JDBC?
•
A API Java padrão para acessar bases de dados
relacionais
–
•
Esconde da aplicação os detalhes específicos do banco de dados
Parte do Java SE (J2SE)
–
Java SE 6 tem o JDBC 4
4
A API JDBC
•
Define um conjunto de interfaces Java, as quais são
implementadas por Drivers JDBC específicos para o
SGBD em uso
–
•
A maior parte da API JDBC está localizada no pacote
java.sql
–
•
As aplicações usam esse conjunto de interfaces Java para
realizar operações no banco de dados → portabilidade
DriverManager, Connection, ResultSet,
DatabaseMetaData, ResultSetMetaData,
PreparedStatement, CallableStatement e Types
Outras funcionalidades avançadas, estão disponíveis no
pacote javax.sql
–
DataSource
5
O driver JDBC
•
Implementação das interfaces JDBC para um banco de
dados específico
–
•
Todo SGBD tem um (ou mais) driver(s) JDBC específicos
Você pode encontrar a lista de drivers disponíveis em:
–
http://industry.java.sun.com/products/jdbc/drivers
6
URL do Banco de Dados
•
Usada para estabelecer uma conexão com o banco de
dados
–
•
Pode conter o servidor, porta, protocolo, etc.
jdbc:subprotocol:subname
–
Derby
jdbc:derby://host_name:port/dbname
–
Oracle Type 4 JDBC Driver.
jdbc:oracle:thin:@machine_name:port_number:instance_name
–
MySQL Connector/J JDBC Driver.
jdbc:mysql://host_name:port/dbname
7
Passo a passo
Uso da API JDBC
8
Passos para usar JDBC
•
Carregue o driver JDBC específico para o banco de
dados em uso
•
Obtenha um objeto Connection
•
Obtenha um objeto Statement
•
Execute consultas e/ou atualizações
•
Leia os resultados
•
Leia os metadados (opcional)
•
Feche os objetos Connection e Statement
9
1. Carregue o driver JDBC específico para o
banco de dados em uso
•
Para carregar manualmente o driver do banco de dados e
registrá-lo com o DriverManager carregue o arquivo
.class
–
Class.forName(<driver do banco de dados>)
10
Exemplo: carregando uma instância do driver
JDBC
11
2. Obtenha um objeto Connection
•
A classe DriverManager é responsável por selecionar o
banco de dados e por criar a conexão com o banco de
dados
–
•
A maneira preferível de obter um objeto Connection é através da
classe DataSource (falaremos sobre isso mais tarde)
Crie a conexão com o banco de dados da seguinte forma:
12
DriverManager & Connection
•
java.sql.DriverManager
–
•
getConnection(String url, String user, String password)
throws SQLException
java.sql.Connection
–
–
–
–
–
Statement createStatement() throws SQLException
void close() throws SQLException
void setAutoCommit(boolean b) throws SQLException
void commit() throws SQLException
void rollback() throws SQLException
13
3. Obtenha um objeto Statement
•
•
Use o objeto Connection para obter uma instância de
Statement
–
java.sql.Statement
• ResultSet executeQuery(String sql)
• int executeUpdate(String sql)
–
Exemplo:
O mesmo objeto Statement pode ser usado para várias
consultas não relacionadas
14
4. Execute consultas e/ou atualizações
•
A partir do objeto Statement, os dois comandos mais
utilizados são:
–
CONSULTA (SELECT)
–
ALTERAÇÕES (INSERT/UPDATE/DELETE)
15
5. Leia os resultados
•
Percorra o ResultSet (usando um laço) recuperando
informações
–
•
java.sql.ResultSet
• boolean next()
• xxx getXxx(int numeroColuna)
• xxx getXxx(String nomeColuna)
• void close()
O iterator é inicializado em uma posição anterior à
primeira linha
–
Você deve chamar next() uma vez para mover o cursor para a
primeira linha
16
5. Leia os resultados (continuação)
•
Uma vez obtido um ResultSet (através de um
statement.executeQuery()), você pode recuperar
facilmente os dados percorrendo o ResultSet
17
5. Leia os resultados (continuação)
•
Ao recuperar os dados de um ResultSet, use o método
getXxx() apropriado
–
–
–
–
•
getString()
getInt()
getDouble()
getObject()
Existe um método getXxx apropriado para cada tipo de
dados definido em java.sql.Types
18
6. Leia os metadados do ResultSet e do banco
de dados (opcional)
•
Uma vez que você disponha dos objetos ResultSet ou
Connection, é possível obter os metadados do banco de
dados ou da consulta
•
Dessa forma, é possível obter informações valiosas sobre
o dado que você está recuperando ou sobre o banco de
dados que você está usando
19
Exemplo de DatabaseMetaData
•
A classe DatabaseMetaData tem, aproximadamente, 150
métodos
20
DataSource &
Pool de Conexões
21
Sub-Tópicos
•
A interface DataSource e o objeto DataSource
•
Propriedades do objeto DataSource
•
Registro JNDI de um objeto DataSource
•
Objeto DataSource que implementa um pool de conexões
•
Recuperação de um objeto DataSource (dentro de sua
aplicação)
22
A Interface javax.sql.DataSource e o Objeto
DataSource
•
Os vendedores do driver JDBC implementam a interface
•
O objeto DataSource é a fábrica para a criação de
conexões com o banco de dados
23
A Interface javax.sql.DataSource e o Objeto
DataSource
•
Três tipos de implementações possíveis:
–
Implementação básica: gera objetos Connection padrão
–
Implementação de um pool de conexões: gera um objeto
Connection que, automaticamente, faz parte de um pool de
conexões
–
Implementação de transações distribuídas: produz um objeto
Connection que pode ser usado para transações distribuídas e,
quase sempre, participa de um pool de conexões
24
Propriedades de um objeto DataSource
•
Um objeto DataSource tem propriedades que podem ser
modificadas quando necessário – essas são definidas em
um arquivo de configuração do container
–
localização do servidor de bancos de dados
–
nome do banco de dados
–
protocolo de rede usado para comunicar com o servidor
•
Benefício: uma vez que as propriedades do objeto
DataSource podem ser alteradas, qualquer código que
acessa a fonte de dados não precisa ser alterado
•
No servidor de aplicações da Sun, uma fonte de dados é
chamada de um recurso JDBC
25
Onde são definidas as propriedades de um
DataSource?
•
Em um arquivo de configuração do container
•
No servidor de aplicações da Sun, elas são definidas em
–
•
<J2EE_HOME>/domains/domain1/config/domain.xml
No Tomcat, elas são definidas no arquivo server.xml
–
<TOMCAT_HOME>/conf/server.xml
26
A definição de uma fonte de dados (recurso
JDBC) no arquivo domain.xml (Sun App Server)
27
28
29
Registro JNDI de um objeto DataSource
•
Um driver acessado através de um objeto DataSource
não registra a si mesmo junto ao DriverManager
•
Ao invés disso, um objeto DataSource é registrado pelo
container em um serviço de nomes JNDI e então é
recuperado pelo cliente através de uma operação de
pesquisa
•
Em uma implementação básica, a conexão obtida através
de um objeto DataSource é idêntica àquela obtida através
de uma facilidade do DriverManager
30
Registro JNDI de um objeto DataSource
(Recurso JDBC)
•
O nome JNDI de um recurso JDBC é esperado no
subcontexto java:comp/env/jdbc
–
•
Por exemplo, o nome JNDI do recurso correspondente ao banco
de dados BookDB poderia ser:
java:comp/env/jdbc/BookDB
Uma vez que todos os nomes JNDI estão no subcontexto
java:comp/env, quando você especificar o nome de um
recurso JDBC, entre somente jdbc/nome. Por exemplo,
para um banco de dados de pagamentos, especifique
jdbc/BookDB
31
Por que um pool de conexões?
•
Uma conexão a um banco de dados é um recurso caro e
limitado
–
•
Usando um pool de conexões, um número menor de conexões
podem ser compartilhadas por um número maior de clientes.
Criar e destruir conexões a um banco de dados são
operações caras
–
Em um pool de conexões, um conjunto de conexões é pré-criado
e disponibilizado à medida em que as aplicações solicitam
conexões. Reduz-se assim o overhead de criar e destruir
conexões ao banco de dados.
32
Pool de conexões e objetos DataSource
•
Objetos DataSource que implementam um pool de
conexões também produzem uma conexão para a fonte
de dados particular representada pela classe DataSource
•
O objeto conexão retornado pelo método getConnection é
um handler para um objeto do tipo PooledConnection, ao
invés de uma conexão física
–
O código da aplicação funciona da mesma forma
33
Exemplo: Criando um recurso JDBC no SJSAS
(Glassfish)
•
Vamos criar um recurso JDBC para acessar um banco
de dados SQL
1.
Obtenha o driver JDBC para o MySQL no endereço
http://dev.mysql.com/downloads/connector/j/5.1.html
2.
Mova o arquivo mysql-connector-java-5.1.6-bin.jar para o
diretório "%J2EE_HOME%\lib\ext\"
3.
(Re)Inicie o Servidor de Aplicações e, no console do
Administrador, crie uma nova Connection Pool
Common Tasks → Other Tasks → Create New JDBC
Connection Pool
34
Exemplo: Criando um recurso JDBC no SJSAS
(Glassfish)
4.
Use os seguintes valores:
Name: MySQLPool
Resource Type: javax.sql.ConnectionPoolDataSource
Database Vendor: MySQL
[NEXT]
5.
Preencha os seguintes valores para as propriedades
adicionais:
ServerName: 127.0.0.1
User: (um usuário existente)
Password: (a password do usuário)
URL: jdbc:mysql://localhost/<nome do banco de dados>
[FINISH]
35
Exemplo: Criando um recurso JDBC no SJSAS
(Glassfish)
6.
Associe a Connection Pool criada a um nome JNDI
Resources → JDBC → JDBC Resources → New
7.
Na tela que se abre, preencha os campos conforme a
figura a seguir e, em seguida, pressione o botão OK.
36
Recuperação e uso de um objeto DataSource
•
A aplicação realiza uma operação de busca JNDI para
recuperar um objeto DataSource
•
O objeto DataSource é então usado para recuperar um
objeto Connection
•
O arquivo do servidor de aplicações domain.xml é usado
para fornecer informações sobre o recurso externo
•
O mapeamento do recurso externo para o nome JNDI é
também realizado no Sun Java System Application
Server (SJSAS)
37
Exemplo: Recuperação de um objeto
DataSource através do JNDI
public class TestDBAO {
Connection con;
public void operation() {
try {
Context initCtx = new InitialContext();
DataSource ds =(DataSource)initCtx.lookup(
"jdbc/testDB");
con = ds.getConnection();
// ...
} catch (Exception ex) {
}
}
}
38
Transações
39
Transações
•
Um dos principais benefícios do uso de um
PreparedStatement é executar os comandos SQL em um
modo transacional.
•
A confirmação de cada comando, assim que ele é
executado, gasta muito tempo
•
Atribuindo o valor false à propriedade AutoCommit, o
desenvolvedor pode atualizar a base de dados mais de
uma vez e então confirmar toda a transação como um
todo
•
Além disso, se cada comando é dependente do outro,
toda a transação pode ser desfeita e o usuário notificado.
40
Métodos de uma Transação JDBC
•
setAutoCommit()
–
•
•
se true, cada comando executado é imediatamente confirmado
commit()
–
relevante somente se setAutoCommit(false)
–
Confirma as operações realizadas desde a abertura de uma conexão ou
desde a última chamada a um commit() ou a um rollback()
rollback()
–
relevante somente se setAutoCommit(false)
–
cancela todas as operações pendentes
41
Exemplo de Transações
42
43
Prepared &
Callable Statements
44
O que são?
•
PreparedStatement
–
•
SQL é enviado para o banco de dados e compilado ou preparado
antecipadamente
CallableStatement
–
Executa as Stored Procedures
45
PreparedStatement
•
O comando SQL é enviado para o Banco de Dados e
compilado ou preparado antecipadamente
•
Desse ponto em diante, o comando SQL preparado é
enviado e esse passo não mais é executado. O objeto
Statement requer esse passo em toda execução.
•
Dependendo do mecanismo do BD, o comando SQL
pode ir para um cache e reutilizado, mesmo que outro
objeto PreparedStatement seja utilizado. Nesse caso, a
maior parte do trabalho é feita pelo BD e não pelo driver.
46
PreparedStatement (cont.)
•
Um PreparedStatement pode receber N parâmetros
correspondentes aos valores das colunas. Esses
argumentos funcionam de maneira muito similar aos
argumentos de um método.
•
Os PreparedStatements lidam com as conversões de
dados que podem ser propensas a erros
quando construídas direta e apressadamente em SQL
–
manipulação de aspas e datas de uma maneira transparente para
o usuário
47
Passos para a utilização de um
PreparedStatement
1.
Registre o driver e crie a conexão com o BD da forma
usual.
2.
Uma vez que você tenha a conexão ao BD, crie o objeto
PreparedStatement
48
Passos para a utilização de um
PreparedStatement (cont.)
3.
Atribua valores aos parâmetros do comando. A
referência aos parâmetros é posicional.
4.
Uma vez que tenham sido atribuídos valores a todos os
parâmetros, execute o PreparedStatement
49
Passos para a utilização de um
PreparedStatement (cont.)
•
Se AutoCommit é igual a true, as modificações são
confirmadas tão logo o comando seja executado. Desse
ponto em diante, você pode reutilizar o objeto
PreparedStatement.
50
Passos para a utilização de um
PreparedStatement (cont.)
•
Se o objeto PreparedStatement contém uma declaração
SELECT então, após executá-lo, você percorre o
ResultSet resultante usando um laço, da mesma forma
que fizemos no exemplo de uso dos Statements.
51
CallableStatement
•
A interface usada para executar stored procedures
•
Uma stored procedure é um grupo de comandos SQL
que formam uma unidade lógica e executam uma tarefa
específica
•
Stored Procedures são usadas para encapsular um
conjunto de operações ou consultas a serem executadas
em um servidor de bancos de dados.
52
CallableStatement (cont.)
•
Um objeto do tipo CallableStatement contém uma
chamada a uma stored procedure; ele não contém a
stored procedure.
•
A primeira linha do código a seguir cria uma chamada
para a stored procedure chamada
MOSTRA_PRODUTOS usando a conexão con.
•
A parte delimitada por chaves contém a sintaxe de
escape para a chamada de procedimentos armazenados.
53
Exemplo de Stored Procedure
CREATE PROCEDURE `MOSTRA_PRODUTOS`()
BEGIN
SELECT * FROM Produto;
END
54
Exemplo de Stored Procedure
•
Uma stored procedure pode ainda receber parâmetros.
Esses parâmetros pode ser de entrada (IN, default),
saída (OUT) e entrada/saída (INOUT)
A seguir um exemplo usando parâmetros de entrada e
saída:
55
Exemplo MySQL
•
A seguir um exemplo de código que usa a stored
procedure do slide anterior
56
Download