Você está na página 1de 67

Universidade Federal de Campina Grande

Disciplina: Banco de Dados I


Professor: Cludio de Souza Baptista
Estagirio Docente: Vincius de Arajo Porto

http://www.lsi.dsc.ufcg.edu.br/

Introduo
Arquiteturas JDBC
JDBC bsico
JDBC avanado

JDBC um conjunto de classes e interfaces (API)


para acessar quaisquer dados em formato tabular
que estejam armazenados em tabelas ou em
arquivos;

Torna fcil enviar statements SQL para os


BDs, mas vai alm do SQL pois permite
interagir com outros tipos de fontes de
dados, como arquivos
Interoperabilidade: o mesmo programa Java
acessa Oracle, Sybase ou MySQL
Serve de base para outras APIs, como SQLJ,
JDO, EJB e JPA

Caractersticas:
fcil mapeamento objeto para relacional;
independncia de banco de dados;
independente de plataforma;

Simplificando, JDBC realiza as seguintes


tarefas:

Estabelece uma conexo com um banco de dados


Executa comandos SQL DDL e DML
Recebe um conjunto de resultados
Executa stored procedures
Obtm informaes sobre o banco de dados
(metadados)
Executa transaes

Exemplo:
Connection con =
DriverManager.getConnection(jdbc:meuDriver:meuDB,
meuLogin, minhaPassword);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
Select matricula, nome from Empregado);
While (rs.next()) {
int mat = rs.getInt(matricula);
String nome = rs.getString(nome);
System.out.println( mat + , + nome );

}
rs.close();

Carregando o driver: cria uma instncia do


driver e registra com o DriverManager
Driver JDBC da oracle:

Class.forName ("oracle.jdbc.driver.OracleDriver");

Ponte JDBC-ODBC:
Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);

Criando uma conexo:


Connection con = DriverManager.getConnection(
url, meulogin, minhaPassword);

Exemplo de URL:
"jdbc:oracle:thin:@localhost:1521:MyDB"

// cria um statement na conexo aberta


Statement stmt = con.createStatement();
stmt.executeUpdate(
CREATE TABLE Empregado +
(matricula int, nome varchar(20), +
endereco varchar(32), salario float)
);

stmt.executeUpdate(
INSERT INTO Empregado values+
(1000, Biliu, Rua das Cruzetas, Sem
Futuro, Brasil, 30.000)
);

JDBC retorna resultados num objeto da


classe ResultSet

ResulSet rs = stmt.executeQuery(
Select * from empregado);

O mtodo next() da classe ResultSet


usado para avanarmos o cursor para a
prxima tupla no resultado:

while(rs.next()) {

Mtodos getXXX()

while (rs.next()) {
int mat = rs.getInt(Matricula);
String nome = rs.getString(Nome);
String endereco = rs.getString(Endereco);
float salario = rs.getFloat(Salario);
}

Mtodos getXXX()
while rs.next()) {
int mat = rs.getInt(1);
String nome = rs.getString(2);
String endereco = rs.getString(3);
float salario = rs.getFloat(4);
}

String updateString =
Update Empregado set salario = salario *
1.1 where salario < 1000.00;
stmt.executeUpdate(updateString);

Mapeamento
entre tipos
SQL e tipos
Java:

SQL type

Java Type

CHAR

String

VARCHAR

String

LONGVARCHAR

String

NUMERIC

java.math.BigDecimal

DECIMAL

java.math.BigDecimal

BIT

boolean

TINYINT

byte

SMALLINT

short

INTEGER

int

BIGINT

long

REAL

float

FLOAT

double

BINARY

byte[]

DATE

java.sql.Date

TIME

java.sql.Time

TIMESTAMP

java.sql.Timestamp

Usado principalmente quando queremos


passar parmetros pelo SQL.

Muitas vezes o comando j vai para o SGBD


compilado o que reduz seu tempo de
processamento.

Exemplo:

PreparedStatement updateSalario = con.prepareStatement(


UPDATE Empregado set salario = ? where matricula = ?);

Precisamos suprir os valores que esto com


?.

PreparedStatement updateSalario = con.prepareStatement(


UPDATE Empregado set salario = ? where matricula = ?);
updateSalario.setFloat(1, 10000);
updateSalario.setInt(2, 1000);
updateSalario.executeUpdate();

Equivalente a :

stmt.executeUpdate(UPDATE Empregado set salario =


10000 where matricula = 1000);

Outro exemplo:
PreparedStatement updateSalarios;
String updateString =
UPDATE Empregado set salario = ? where matricula = ?;

updateSalarios = con.prepareStatement(updateString);
int [] novosSalarios = {2000, 1500, 3000, 500};
int [] matriculas = {1000, 1050, 2000, 1078};
int tam = matriculas.length;
for( i = 0 ; i < tam; i++) {
updateSalarios.setfloat(1, novosSalarios[i]) ;
updateSalarios.setInt(2, matriculas[i]);
updateSalarios.executeUpdate();
}

Aps o uso precisamos fechar o statement e


a conexo usando os mtodos:
stmt.close();
con.close();

Um objeto que pode ser usado para obter


informaes sobre os tipos e propriedades das
colunas em um ResultSet;
Exemplo:

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM


TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
String colName = getColumnName(1);
boolean b = rsmd. isReadOnly(int column);
...

Um objeto que pode ser utilizado para obter


informaes sobre o SGBD
Exemplo:

DatabaseMetaData dbmd = con.getMetaData();


ResultSet rs = dbmd.getPrimaryKeys(null, null, SUPPLIERSPK);
while (rs.next()){
System.out.println(Tabela: + rs.getString(TABLE_NAME);
System.out.println(Coluna: + rs.getString(COLUMN_NAME);
}

Pacote javax.sql.*
A API JDBC possui caractersticas como:
scroll para frente e para trs num result set
realizao de updates em tabelas do BD usando mtodos
Java (ao invs de SQL)
Enviar comandos batch
Usar novos tipos de dados SQL3
Criar novos tipos definidos pelo usurio (SQL UDT)
Mapear um SQL UDT para uma classe em Java
Fazer uma conexo que pode ser usada num transao
distribuda
Etc.

O ResultSet default no updatable e tem um


cursor que se move somente para frente;
createStatement(int resultSetType, int
resultSetConcurrency)
resultSetType:
ResultSet.TYPE_FORWARD_ONLY
ResultSet.TYPE_SCROLL_INSENSITIVE
ResultSet.TYPE_SCROLL_SENSITIVE

resultSetConcurrency
ResultSet.CONCUR_READ_ONLY
ResultSet.CONCUR_UPDATABLE

Exemplo:
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet srs = stmt.executeQuery(
select * from empregado);

Movendo o cursor pra trs


Statement stmt =
con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY
);
ResultSet srs = stmt.executeQuery(
select nome, salario from empregado
);
srs.afterLast();
// coloca o cursor aps a ltima tupla
while (srs.previous()) {
String nome = srs.getString(Nome);
Double salario = srs.getDouble(Salario);
System.out.println(nome + + salario);
}

Movendo o cursor para uma linha


especfica:

first();
last();
beforeFirst();
afterLast();
absolute(i);
relative(i);

Exemplos:
srs.absolute(-4): move para a 4 tupla do final do
ResultSet, ou seja, se srs tiver 500 tuplas, ento
move para tupla 497
srs.absolute(4): // move cursor para a quarta linha
srs.relative(-3): // move o cursor para a primeira
linha
srs.relative(2): // move o cursor para a terceira
linha

getRow(): indica o nmero da linha em que


o cursor aponta
Exemplo:

srs.absolute(4);
int linhaCorrente = srs.getRow();

retorna 4

Outras funes:

isFirst();
isLast();
isBeforeFirst();
isAfterLast();

Exemplo:
if(!srs.isAfterLast()) {

Criando um ResultSet atualizvel


Connection con =

DriverManager.getConnection(jdbc:meuSubProtocolo:me
usDados, user, password);
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet. CONCUR_UPDATABLE);
ResultSet uprs = stmt.executeQuery(
Select nome, salario from Empregado);
uprs.last();
uprs.updateDouble(Salario, 1000.00);
uprs.updateRow(); // leva o update para o BD

Podemos cancelar o update no refletindo


seus valores no BD usando:
uprs.cancelRowUpdates();

Connection con = DriverManager.getConnection


(jdbc:meuSubProtocolo:meusDados);
Statement stmt = con.createStatement
(ResultSet.TYPE_SCROLL_SENSITIVE,
Move para um buffer
ResultSet. CONCUR_UPDATABLE);
onde novas linhas
ResultSet uprs = stmt.executeQuery(
podem ser criadas
Select * from Empregado);
uprs.moveToInsertRow();
uprs.updateInt(Matricula, 1001);
uprs.updateString(Nome, Ze Maria);
uprs.updateString(Endereco, Rua A, num 199, Zepa);
uprs.updateDouble(Salario, 3000.00);
uprs.insertRow();

uprs.absolute(4);
uprs.deleteRow();

try {
// Comandos
} catch (SQLException e) {
System.out.println(
SQLException:+e.getMessage());
}
Mensagem impressa:
SQLException: There is already an object called
Empregado in the database.

try {
// comandos
} cacth(SQLException e) {
System.out.println(SQLException capturada:);
while (e != null) {
System.out.println(Mensagem: + e.getMessage());
System.out.println(SQLState: + e.getSQLState());
System.out.println(ErrorCode: + e.getErrorCode());
e = e.getNextException();
}
}
Exemplo:
SQLException capturada:
Mensagem: ORA-00942: a tabela ou view no existe
SQLState: 42000
ErrorCode: 942

SQLWarning subclasse de SQLException;


No param a execuo de uma aplicao;
Servem para alertar o usurio de que algo
no aconteceu como previsto.

Exemplo:

Statement stmt = con.createStatement();


ResultSet rs = executeQuery(select mat from empregado);
SQLWarning aviso = stmt.getWarnings();
if (aviso != null) {
System.out.println(Warnings:);
while (aviso != null) {
System.out.println(Mensagem: + aviso.getMessage());
System.out.println(SQLState: + aviso.getSQLState());
System.out.println(ErrorCode:+aviso.getErrorCode());
aviso = aviso.getNextWarning();
}
}

Nos permite enviar vrios comandos de update


num nico lote ao invs de individualmente;
Melhor desempenho;
Comandos:
addBatch(String comando);
clearBatch();

Os comandos podem ser update, insert, delete e


comandos DDL (create table, drop table)
Comando SELECT no pode ser usado!

Exemplo:

con.setAutoCommit(false);
Statement stmt = con.createStatement();
stmt.addBatch(insert into empregado values
Engenheiro, 1500.00));
stmt.addBatch(insert into empregado values
Engenheiro, 1800.00));
stmt.addBatch(insert into empregado values
Motorista, 500.00));
stmt.addBatch(insert into empregado values
Mecanico, 800.00));
int [] updateCounts = stmt.executeBatch();
con.commit();
con.setAutoCommit(true);

(100, Joao,
(200, Maria,
(300, Pedro,
(400, Jose,

um objeto que encapsula um conjunto de


linhas que foram retiradas de um Data
Source;
Essas linhas so acessveis atravs da
interface javax.sql.RowSet;
RowSet estende a interface ResultSet, ou
seja, o RowSet pode fazer tudo que um
ResultSet faz;

RowSet um componente javaBeans:

adiciona e remove event listener (RowSetListener);


get e set para todas as suas propriedades

Um RowSet permite estabelecer uma conexo


com database e executar uma consulta para
preench-lo de dados;
Em geral, a API JDBC pode ser dividida em duas
partes:
a parte RowSet
a parte do driver

RowSet uma camada de software que roda


acima do driver JDBC

RowSet pode ser


Conectado: mantm conexo com o DataSource
todo o tempo em que usado;
Desconectado: permanece conectado ao
DataSource apenas quando est lendo ou
escrevendo

Atributos de um RowSet
A interface RowSet fornece um conjunto de
propriedades que permite que uma instncia seja
configurada para conectar ao DataSource e obter
um conjunto de linhas

Exemplo:

rset.setDataSourceName("jdbc/SomeDataSourceName");
rset.setUsername(fernanda);
rset.setPassword(secret);
rset.setQueryTimeout(20);
rset.setMaxRows(1024);
rset.setTransactionIsolation(
Connection.TRANSACTION_READ_COMMITTED);
rset.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
rset.setCommand("SELECT NAME, SALARY FROM EMPLOYEES");

O mtodo execute() deve ser invocado para que


o RowSet seja preenchido com dados;
Exemplo:
rset.setCommand (
"SELECT empno, ename, sal FROM emp");
rset.execute ();
while (rset.next ()){
System.out.println ("empno: " + rset.getInt (1));
System.out.println ("ename: + rset.getString (2));
System.out.println ("sal: " + rset.getInt (3));
}

Usando parmetros:
rset.setCommand(SELECT NAME, SALARY FROM EMPLOYEES
WHERE DEPT = ? OR DEPT= ?);
rset.setString(1, SALES);
rset.setString(2, MARKETING)

Qualquer parmetro em um RowSet deve


ser setado antes da chamada funo
execute():

Mover o cursor em RowSet exatamente da


mesma forma que um scrollable ResultSet;
Exemplo:

...
rset.beforeFirst();
while(rset.next()){
System.out.println(rset.getString(1) + +
rset.getFloat(2);
}
...

Evento
Trs tipos de eventos podem ocorrer:
O cursor pode mover;
Suas linhas podem mudar (insert, delete ou update);
O contedo inteiro do RowSet pode mudar

Os listeners devem implementar a interface


RowSetListener;

RowSetListener

Aplicao

add

cursorMoved(RowSetEvent)

RowSet

addRowSetListener

rowChanged(RowSetEvent)

removeRowSetListener

rowSetChanged(RowSetEvent)

evento

Metadados
A interface RowSetMetaData contem informaes
sobre as colunas de um objeto RowSet;
Essa interface uma extenso de
ResultSetMetaData;

Exemplo:
RowSetMetaData rsetmd = rset.getMetaData();
int columnCount = rsetmd.getColumnCount();
String colName = rsetmd.getColumnName(intcolumn);

Implementaes da interface RowSet no


J2SE verso 1.5:

JdbcRowSet
CachedRowSet
WebRowSet
FilteredRowSet
JoinRowSet

um RowSet do tipo connected;


Ele sempre mantm a conexo com o data
source;
Pode servir como um wrapper para o
ResultSet

Exemplo:

JdbcRowSet jrs = new JdbcRowSet();


jrs.setCommand(SELECT * FROM TITLES);
jrs.setURL(jdbc:myDriver:myAttribute);
jrs.setUsername(name);
jrs.setPassword(password);
jrs.execute();
...
jrs.absolute(2);
String title = jrs.getString(1);

um RowSet do tipo Disconnected;


No precisa manter uma conexo aberta
com data source;
Uma aplicao pode modificar os dados em
um CachedRowSet e estas modificaes
podem ser propagadas de volta para o
data source;

Tornando um ResultSet com capacidades de


scrolling e update atravs do
CachedRowSet:

ResultSet rs = stmt.executeQuery(
SELECT * FROM EMP);
CachedRowSet crset = new CachedRowSet();
crset.populate(rs);
...
crset.last();
String name = crset.getString(1);

Atualizando dados:

crset.setCommand(SELECT NAME, SALARY FROM


EMPLOYEES);
crset.execute();
...
crset.first();
crset.updateString(1, Jane Austen);
crset.updateFloat(2, 150000f);
crset.updateRow();

Estende a interface CachedRowSet,


portanto tem as mesmas capacidades;
Tem a habilidade de ler e escrever RowSet
no formato XML;

Exemplo:
Escrevendo um XML

WebRowSetImpl wrs = new WebRowSetImpl();


wrs.populate(rs);
wrs.absolute(2);
wrs.updateString(1, new String);
FileWriter fWriter = new FileWriter(output.xml);
wrs.writeXml(fWriter);

Exemplo:
Lendo um XML
WebRowSetImpl wrs = new WebRowSetImpl();
FileReader fReader = new FileReader(output.xml);
wrs.readXML(fReader);
wrs.absolute(2);
String str = wrs.getString(1);

um extenso de CachedRowSet;
Permite ao usurio filtrar um subconjunto
de dados de um RowSet;
Por exemplo: supondo que o FilteredRowSet
contm todos os empregados de uma
empresa e queremos informaes dos
empregados que estejam entre Ana e Lee.

Exemplo:

FilteredRowSet frs = new FilteredRowSetImpl();


frs.populate(rs);
Range names = new Range("Ana", Lee",
findColumn(NAME));
frs.setFilter(names);
while(frs.next()){
String name = frs.getString(NAME);
}

Permite o programador combinar dados de


diferentes RowSet;
Pode ser til quando precisamos unir dados
de diferentes data source;
Depois do Join, cada linha do
JoinRowSetImpl ir conter as colunas de
ambos os RowSets que pertenam ao
mesmo ID.

Exemplo:

JoinRowSet jrs = new JoinRowSetImpl();


ResultSet rs1 = stmt.executeQuery("SELECT * FROM EMPLOYEES");
CachedRowSet empl = new CachedRowSetImpl();
empl.populate(rs1);
empl.setMatchColumn(1);
jrs.addRowSet(empl);
ResultSet rs2 = stmt.executeQuery("SELECT * FROM BONUS_PLAN");
CachedRowSet bonus = new CachedRowSetImpl();
bonus.populate(rs2);
bonus.setMatchColumn(1); // EMP_ID is the first column
jrs.addRowSet(bonus);
jrs.first();
int employeeID = jrs.getInt(1);
String employeeName = jrs.getString(2);

Maydene Fisher, Jon Ellis, Jonathan Bruce,


JDBC API Tutorial and Reference,
Addison-Wesley Pub Co, 2003, 3 Edio
Manuais da Oracle

http://www.oracle.com/technology/documentation
/index.html

Você também pode gostar