A API JDBC disponibiliza diversos serviços para manipulação de Banco de Dados, como por exemplo, métodos que gerenciam a conexão com o banco ou objetos que trabalham com resultados obtidos.

A responsabilidade principal da interface Statement é executar sentenças SQL no banco de dados. O caso mais comum é a execução de SQL de consulta (a sentença SELECT), que vai gerar um conjunto de dados na resposta, o ResultSet:

   ...     Connection con = DriverManager.getConnection(...); 
     Statement stm = con.createStatement(); 
  
     ResultSet rs = stm.executeQuery("SELECT NOME, TEL FROM CLIENTES"); 
     ...

O ResultSet, objeto responsável por manipular os dados obtidos da execução de uma query, é o foco deste tutorial, que mostrará o comportamento interessante deste objeto: o Scrollable ResultSet.

  • Navegabilidade refere-se à capacidade de navegar para frente e para trás nas linhas contidas em um ResultSet.
  • Posicionamento é a capacidade de mover o cursor corrente para uma outra posição dentro do ResultSet.
  • Manipulação é a capacidade de alterar os valores contidos em um ResultSet.

Este tipo de ResultSet tem a capacidade de Navegabilidade e de Posicionamento, para isso, ele utiliza três chamadas diferentes para objetos Statement:

connection.createStatement(int resultSetType, int resultsetConcurrency);
 connection.preparedStatement(String sql, int resultSetType, int resultSetConcurrency);
 connection.prepareCall(String sql, int resultSetType, int resultSetConcurrency);

O parâmetro resultSetType define se o ResultSet irá ser navegável e posicionado ou não:

  • ResultSet.TYPE_FORWARD_ONLY: com este parâmetro o ResultSet não poderá ser navegável, ou seja, poderemos somente avançar no objeto ResultSet para poder buscar valores.
  • ResultSet.TYPE_SCROLL_INSENSITIVE: com este parâmetro o ResultSet poderá ser navegável em qualquer direção, para frente e para trás, e será insensível a mudanças feitas por outras transações ou por outros Statements da mesma transação.
  • ResultSet.TYPE_SCROLL_SENSITIVE: com este parâmetro o ResultSet poderá ser navegável para qualquer direção, e será sensível a mudanças feitas por outras transações ou por outros Statements da mesma transação.

Para prover a navegabilidade e o posicionamento, a classe ResultSet possui vários métodos.Ex:

  • boolean first(): posiciona o cursor na primeira linha do ResultSet e retorna true, caso não exista linhas, retorna false.
  • boolean last(): posiciona o cursor na última linha do ResultSet e retorna true, caso não exista linhas, retorna false.
  • boolean previous(): posiciona o cursor para a linha anterior a posição corrente, retorna true caso a linha seja válida e false caso contrário.

Aplicando o que foi passado é possível criar uma aplicação que simula um DBNavigator do Delphi. Ou seja, é possível criar uma aplicação para “navegar” nos registro que foram consultados em uma tabela do banco de dados:

  1. criar um JFrameForm
  2. criar a conexão, utilizando uma ponte JDBC/ODBC, por exemplo, no método construtor
  3. executar um dos três tipos de comandos Statment citados anteriormente. Ex:
    con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
  4. inserir os componentes gráficos, um Jlabel e um JTextField para cada campo da tabela, retornado na consulta do comando SQL.
  5. Inserir os botões de navegação nos registros: primeiro, próximo, anterior e ultimo.
  6. Inserir as ações dos eventos destes botões.

Exemplo

Criar uma aplicação para navegar no resultado da consulta de todos os campos da tabela “TbAgenda”, composta dos seguintes campos:

  • Numero: tipo texto;
  • Nome: tipo Texto;

Supondo que o banco e a conexão ODBC, “BDAgenda”, já foram criadas: (Em caso de dúvida quanto à estas operações, veja os tutorias publicados anteriormente):

1º - Criar uma classe “Java Gui Forms”: clique no menu File à New File.

Na janela que se abre selecione Java Gui Forms à JFrameForm à Next, insira o nome da classe, DBNavigator, no campo “Class Name”. Clique em Finish.

2º - Criar a parte gráfica: insira dois JLabel e dois JTextField para mostrar os dados dos registros.

  • insira também quatro JButton (Primeiro, Próximo, Anterior, Ultimo) para permitir a navegação.
  • insira mais dois botões: um JToggleButton, “Carregar Dados” e um JButton, “Sair”:

jvmbcarntfig01.jpg

Obs1: Para implementar as ações dos botões é preciso importar os pacotes necessários para realizar as devidas operações SQL e utilizar os componentes de exibição dos resultados. Antes do comando de criação da Classe:

public class DBNavigator{
 Insira os comandos de import:
 import java.sql.*;
 import javax.swing.*;

Obs2: O Resultado da consulta SQL será guardado dentro de um ResultSet que por sua vez será compartilhado por todos os botões. Então este resultado deve ser guardado dentro de uma variável global, fora dos métodos. Localize o método construtor da classe:

public DBNavigator(){
 ...

Antes deste comando insira a declaração da variável do tipo ResultSet. Ex:

ResultSet RS;

O código completo deverá ficar parecido com:

jvmbcarntfig02.jpg

3º - Criar a ação do botão “Carregar Dados”: clique com o botão direito do mouse sobre o botão “Carregar Dados” à Evento actionPerformed. Insira os códigos abaixo:

        try{ //tratamento de erros
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//busca Driver
 //conecta no BD
        Connection con=DriverManager.getConnection("jdbc:odbc: BDAgenda ","","");
        Statement stmt =
 con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        RS= stmt.executeQuery("Select * from TbAgenda");
        } catch(SQLException e){ //trata os erros
             JOptionPane.showMessageDialog(this,"Erro Cmdo SQL " + e.getMessage());
        } catch(ClassNotFoundException e){     
            JOptionPane.showMessageDialog(this,"Driver não encontrado");
        }   

4º - Criar a ação do botão “Primeiro”. Clique com o botão direito do mouse sobre o botão “Primeiro” à Evento actionPerformed. Insira os códigos abaixo:

      try{
         RS.first();
         jTextField1.setText(RS.getString("Numero"));
         jTextField2.setText(RS.getString("Nome"));
      } catch(SQLException e){ //trata os erros
         JOptionPane.showMessageDialog(this,"Primeiro");        
     }

5º - Criar a ação do botão “Próximo”:

      try{
         RS.next();
         jTextField1.setText(RS.getString("Numero"));
         jTextField2.setText(RS.getString("Nome"));
       } catch(SQLException e){ //trata os erros
 JOptionPane.showMessageDialog(this,"Não Existem mais Registros");
       }

6º - Criar a ação do botão “Anterior”:

      try{
         RS.previous();
         jTextField1.setText(RS.getString("Numero"));
         jTextField2.setText(RS.getString("Nome"));
    } catch(SQLException e){ //trata os erros
  JOptionPane.showMessageDialog(this,"Não Existem mais Registros");
  }  

7º - Criar a ação do botão “Ultimo”:

     try{
         RS.last();
         jTextField1.setText(RS.getString("Numero"));
         jTextField2.setText(RS.getString("Nome"));
            } catch(SQLException e){ //trata os erros
   JOptionPane.showMessageDialog(this,"Ultimo");
            }        
     }

8º - Criar a ação do botão “Sair”:

        System.exit(0);

9º - Compile: F9

10º - Execute: Shift+F6