Nesta atividade de laboratório você irá criar aplicações Java que acessam bancos de dados.
O JDBC permite que aplicações escritas em Java acessem bancos de dados de forma bastante simples. Para acessar o banco de dados é preciso usar um driver JDBC que faça a conexão com o SGBD.
O driver JDBC para o SQL Server pode ser obtido aqui. Outros drivers podem ser encontrados a partir da página dos drivers JDBC que é mantida pela Sun. No caso de bancos de dados compatíveis com ODBC (Open DataBase Connectivity), podemos também usar um driver genérico JDBC para bancos ODBC que é distribuído pela Sun junto com o Java.
Para tornar a nossa aplicação portável entre bancos de dados, usaremos o driver ODBC. Para isto, você deve criar a conexão ODBC com o servidor do banco. Em uma máquina Windows, isto pode ser feito usando o Administrador de fonte de dados ODBC, que fica no painel de controle.
Ao abrir o administrador você verá algo semelhante à janela abaixo. Clique em Adicionar para iniciar a criação da nova fonte de dados.

Na janela seguinte, selecione o SQL Server e clique o botão Concluir.

Em seguida, dê um nome e uma descrição à fonte de dados, selecione o servidor e clique em Avançar.

Na próxima janela, especifique o modo de autenticação, o login e a senha que serão usados para acessar o banco, e depois clique em Avançar novamente.

Em seguida, especifique o nome do banco que será usado e clique mais uma vez em Avançar.

Na janela seguinte, altere as configurações padrão se julgar necessário e clique em Concluir.

Na janela seguinte você pode testar a fonte de dados (para isto é necessário que o servidor esteja rodando). Após testá-la, clique em OK para confirmar a criação.

A partir de agora é possível acessar o banco de dados usando o driver JDBC para servidores ODBC.
O acesso ao banco através de um programa Java é bastante simples. Basta criar a conexão com o banco usando o driver JDBC e em seguida executar a consulta desejada. No programa abaixo foi feita uma consulta ao banco de dados dos clientes de uma instituição financeira, que foi utilizado nas aulas anteriores.
import java.sql.*;
import java.util.*;
public class SelectConta {
public static void main( String args[] ) {
String url = "jdbc:odbc:Banco";
String username = "sa";
String password = "sa";
Connection connection = null;
// Cria a conexão com o banco
try {
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
connection = DriverManager.getConnection( url, username, password );
}
catch ( ClassNotFoundException cnfex ) {
System.err.println( "Driver JDBC/ODBC nao encontrado." );
cnfex.printStackTrace();
System.exit( 1 );
}
catch ( SQLException sqlex ) {
System.err.println( "Falha na conexao." );
sqlex.printStackTrace();
System.exit( 1 );
}
try {
// Executa a query
String query = "select conta, nome, agencia, saldo from contas";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery( query );
// Imprime o resultado
System.out.println( "Contas do Banco" );
System.out.println( "Conta\tNome\tAgencia\tSaldo" );
while ( resultSet.next() ) {
System.out.println( resultSet.getInt( 1 ) + "\t" +
resultSet.getString( 2 ) + "\t" +
resultSet.getInt( 3 ) + "\t" +
resultSet.getFloat( 4 ) );
}
// Fecha a conexão com o banco
statement.close();
connection.close();
}
catch ( SQLException sqlex ) {
sqlex.printStackTrace();
}
}
}
Crie a fonte de dados ODBC e teste o código acima na sua máquina.
Caso deseje exibir os resultados em uma janela, é necessário adicionar o código para criação da interface gráfica e para mostrar os dados obtidos em uma tabela, como neste exemplo adaptado do livro "Java: Como Programar".
Um procedimento armazenado pode ser criado no SQL Server manualmente ou utilizando os Wizards do Enterprise Manager. Neste último caso, podemos criar procedimentos simples para criação de tabelas e para inserção e remoção de dados.
Após conectar ao servidor do banco, os wizards podem ser acessados a partir do menu Tools -> Wizards. Selecione na janela abaixo o "Create Stored Procedure Wizard", que cria procedimentos armazenados, e clique o botão OK.

Na janela que surgirá, selecione a base de dados que será utilizada e clique em Avançar.
Na janela seguinte, indique que queremos criar uma stored procedure para inserção de dados na tabela contas, e clique novamente em Avançar.

Edite as propriedades da stored procedure de modo a remover a coluna rowguid, que foi criada automaticamente pelo SQL Server. Clique em OK para finalizar a criação.

Para acessar este procedimento, faremos algumas alterações no programa anterior para que obtenhamos os parâmetros de chamada da stored procedure e por fim a executemos no banco. O código a seguir mostra estas alterações:
import java.sql.*;
import java.util.*;
import javax.swing.JOptionPane;
public class CriaConta {
public static void main( String args[] ) {
String url = "jdbc:odbc:Banco";
String username = "sa";
String password = "sa";
Connection connection = null;
int agencia = 0;
// Cria a conexão com o banco
try {
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
connection = DriverManager.getConnection( url, username, password );
}
catch ( ClassNotFoundException cnfex ) {
System.err.println( "Driver JDBC/ODBC nao encontrado." );
cnfex.printStackTrace();
System.exit( 1 );
}
catch ( SQLException sqlex ) {
System.err.println( "Falha na conexao." );
sqlex.printStackTrace();
System.exit( 1 );
}
// Cria a conta
try {
Statement statement = connection.createStatement();
// Determina o número da conta
ResultSet resultSet = statement.executeQuery(
"select max(conta) from contas" );
resultSet.next();
int conta = resultSet.getInt(1) + 1;
// Obtém o nome do cliente
String nome = JOptionPane.showInputDialog(null,
"Entre com o nome do cliente:", "Cria Conta",
JOptionPane.QUESTION_MESSAGE);
if (nome == null) { // botão cancel
statement.close();
connection.close();
System.exit(1);
}
// Obtém o número da agência
String ag = JOptionPane.showInputDialog(null,
"Entre com o número da agencia:", "Cria Conta",
JOptionPane.QUESTION_MESSAGE);
if (ag == null) { // botão cancel
statement.close();
connection.close();
System.exit(1);
}
try {
agencia = Integer.parseInt(ag.trim());
} catch (NumberFormatException nfe) {
System.err.println("Código da agência inválido.");
statement.close();
connection.close();
System.exit(1);
}
// Executa a stored procedure
statement.execute( "execute insert_contas_1 " + conta + "," +
nome + "," + agencia + ", 0.00" );
JOptionPane.showMessageDialog(null, "Conta criada com sucesso.",
"Cria Conta", JOptionPane.INFORMATION_MESSAGE);
// Fecha a conexão com o banco
statement.close();
connection.close();
System.exit(0);
}
catch ( SQLException sqlex ) {
sqlex.printStackTrace();
System.exit(1);
}
}
}
Crie a stored procedure no seu servidor e teste o código acima.
Em seguida, crie stored procedures para encerrar contas e para criar e cancelar cartões de crédito.
A execução de transações a partir de aplicações exige alguns cuidados adicionais. Primeiramente precisamos desabilitar a efetivação automática com o método setAutoCommit(false) da conexão com o banco. Os comandos executados a partir de então são interpretados como parte de uma transação, que deve ser efetivada chamando o método commit() ou abortada através do método rollback().
O código abaixo executa uma transação de saque em uma conta corrente do banco.
import java.sql.*;
import java.util.*;
import javax.swing.JOptionPane;
public class SaqueConta {
public static void main( String args[] ) {
String url = "jdbc:odbc:Banco";
String username = "sa";
String password = "sa";
Connection connection = null;
Statement statement = null;
// Cria a conexão com o banco
try {
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
connection = DriverManager.getConnection( url, username, password );
connection.setAutoCommit(false);
}
catch ( ClassNotFoundException cnfex ) {
System.err.println( "Driver JDBC/ODBC nao encontrado." );
cnfex.printStackTrace();
System.exit( 1 );
}
catch ( SQLException sqlex ) {
System.err.println( "Falha na conexao." );
sqlex.printStackTrace();
System.exit( 1 );
}
// Executa o saque
try {
statement = connection.createStatement();
// Obtém o número da conta
String conta = JOptionPane.showInputDialog(null,
"Entre com o número da conta", "Saque",
JOptionPane.QUESTION_MESSAGE);
if (conta == null) { // botão cancel
statement.close();
connection.close();
System.exit(1);
}
// Obtém o saldo atual
ResultSet resultSet = statement.executeQuery(
"select saldo from contas where conta = " + conta );
resultSet.next();
JOptionPane.showMessageDialog(null, "Saldo na conta: R$" +
resultSet.getFloat( 1 ) , "Saque",
JOptionPane.INFORMATION_MESSAGE);
// Obtém o valor do saque
String valor = JOptionPane.showInputDialog(null, "Entre com o valor do saque",
"Saque", JOptionPane.QUESTION_MESSAGE);
if (valor == null) { // botão cancel
statement.close();
connection.rollback();
connection.close();
System.exit(1);
}
// Inicia a transaçao de saque
statement.execute("insert into operacoes " +
"values(" + conta + ",'Saque',"+ valor + ")");
statement.execute( "update contas set saldo = saldo - " + valor +
"where conta = " + conta +"\n" );
// Verifica o saldo restante na conta
resultSet = statement.executeQuery(
"select saldo from contas where conta = " + conta );
resultSet.next();
JOptionPane.showMessageDialog(null, "Saldo após o saque: R$" +
resultSet.getFloat( 1 ) , "Saque",
JOptionPane.INFORMATION_MESSAGE);
// Obtém a confirmação do cliente
int confirm = JOptionPane.showConfirmDialog(null,
"Confirmar o Saque?", "Saque", JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
// Saque confirmado
connection.commit();
JOptionPane.showMessageDialog(null, "Retire o seu dinheiro.",
"Saque", JOptionPane.INFORMATION_MESSAGE);
} else {
// Saque cancelado
connection.rollback();
JOptionPane.showMessageDialog(null, "Saque cancelado.",
"Saque", JOptionPane.ERROR_MESSAGE);
}
// Fecha a conexão com o banco
statement.close();
connection.close();
System.exit(0);
}
catch ( SQLException sqlex ) {
sqlex.printStackTrace();
System.exit(1);
}
}
}
Teste o código acima. Com a transação em execução, tente acessar os dados a partir do Query Analyzer usando diversos modos de bloqueio (mais detalhes aqui). Confirme o saque, e em seguida verifique que os dados foram alterados no banco. Em um segundo momento, cancele a transação e verifique que os dados não foram alterados no banco.
Crie uma aplicação que possa ser usada pelos funcionários de um banco para:
A aplicação poderá ser feita em duplas, devendo ser feita preferencialmente em Java. Se desejar usar outra linguagem, consulte o professor.
A avaliação será efetuada na aula do dia 18/09 no período vespertino.