Dúvida sobre JDBC

Bem pessoal, vamos lá. Considerem o trecho de código a seguir:


String query = “SELECT * FROM CUSTOMER”
ResultSet rs = stmt.executeQuery(query);

Supondo que CUSTOMER tenha 100 mil registros, ao processar o executeQuery(), rs conterá 100 mil registros? Na verdade eu preciso saber se há como se fazer a paginação dos dados - por exemplo, retornar apenas 10 registros por vez e quando necessário ir buscando o restante.

É possível em Java?

Caso não diretamente, existe alguma forma de se conseguir isso? ( não serve colocar isso como responsabilidade do DB, precisa ser resolvido no código do aplicativo…)

Tenho aplicações que utilizam este tipo de recurso usando tecnologia Midas ( Delphi ) - posso controlar facilmente o fluxo de dados “empacotando” eles…

Convenhamos que trafegar 100 mil registros pela Web demoraria uma eternidade…

Desde já, obrigado pela atenção.

Qualquer coisa, tamos aí!
ALEXANDRE ( J2Alex )

Existe um Design Pattern chamado Value Object ( VO ) que pode te ajudar.
Basicamente consiste em retornar um objeto com os dados que voce precisa, ao inves de retornar tudo. Eh necessario a implementacao de uma camada mais high level sobre o JDBC.

De uma olhada no VO ( explicar direito aqui ficaria um pouco grande ).
O ResultSet nao contem os 100.000 registros, ele apenas contem o result resource do sql executado, o que significa que voce nao tera os objetos em memoria de uma vez soh, porem a cada movimentacao no registro acarretara em trafego de rede.

Rafael

DEUS SEJA LOUVADO!

Existe um Bean chamado CachedRowSet que a Sun desenvolveu justamente para fazer paginação de resultados de consultas a BD. O problema é que ele armazena tudo na memória e aí se o BD for grande, haja memória. Mas em alguns casos ele é bastante legal de se usar… Você pode procurar por CachedRowSet no site da sun. Um pró em relação a ele é que é muito fácil de ser utilizado.

Eu ja usei

SELECT * FROM tabela LIMIT 0,10

Ai quando o usuario entrava em

VerDados.jsp?Layout=1&Pagina=2

usava 2 * 5 = 10

entao usava a variavel * 5 :slight_smile:

Limitando…

Porem nao sao todos os banco de dados que suportam LIMIT … SQL Server, Oracle e outros nao tem suporte a esta diretiva.

Rafael

Você pode usar na instrução select “SELECT TOP 10 Nome_campos FROM TABELA”. Não esqueca de usar o ORDER BY para garantir que eles não venham fora de ordem, e armazene um identificador do ultimo registro retornado para que no select você ponha uma clausula “WHERE CampoIdentificador > Variavel ORDER BY CampoIdentificador” . Isso deve resolver se eu entendi.

mas o TOP tambem nao eh suportado por todos os bancos. Value Object continua sendo a melhor saida.

Rafael

Uma dúvida: tráfego em QUAL rede??

Normalmente, vc não vai ter tráfego devido ao resultset na web. Se vc faz um servlet, o bd tá normalmene na sua rede local, e vc monta a página antes de mandar.

Se vc tá usando RMI, normalmente vc não dá um ResultSet na mão do cliente. Vc monta qq estrutura que ele quer e joga o RS fora.

90% das vezes, vc não vai sentir o peso do resultset.

[ ]s

Faz uma enorme diferenca. Talvez em aplicacoes com tudo localhost voce nao sinta tanto, mas ter que ficar enviando pacotes toda hora nao eh a melhor solucao. A coisa complica ainda mais quando tem proxy/firewall ou outra coisa no meio.

Tipo, eu retorno os ResultSet nas minhas aplicacoes, mas sei que nao eh o melhor.

Rafael

Rafael, vc tem métodos remotos que retornam ResultSet?? Acho que não entendi o que vc disse…

Mesmo porque um ResultSet não é necessariamente Serializable.

Outro ponto importante: na maioria das vezes, a sua aplicação roda numa máquina diferente do banco de dados. A conexão de rede é insubstituível, não dá pra fazer nada quanto a isso.

Aliás, a parte mais lenta é abrir conexões, por isso que tem tanta gente fazendo pool.

[ ]s

Nao, remotos nao. Apenas os metodos das classes de negocios que retornam um objeto ResultSet ao inves dos dados em um array ( como no caso do VO )…

Concordo que o gargalo maior realmente esta em abrir a conexao.

Rafael

pessoal!!! DEPENDE!

depende do seu driver de conexao JDBC

a MAIORIA nao coloca tudo na memoria do java quanto te retorna um resultset. ele apenas guada referencia ao resultado da pesquisa diretamente no bancod e dados. quando voce comeca a navegar, ele comeca a puxar o resultado do BD.

eh tipo um “lazy” evaluation.

mas depende do seu jdbc connector

Acho que vou dar uma olhada na especificacao do JDBC. Para testar o que o Paulo disse fiz um progrma simples, que conecta no banco, executa o sql e tal. Entao dou um rs.next() e mostro o primeiro registro. Entao, pra impedir o programa de continuar, espero que uma tecla seja precionada para entar dar um rs.next() e mostrar o proximo registro.

Apos mostrar o primeiro registro, o sistema fica esperando o precionamento de alguma tecla. Neste momento ( usei mysql ), dou shutdown no servidor de banco de dados. Entao preciono uma tecla e o ponteiro do rs.next() eh movido para o proximo resultado, mostrando os dados na tela.

Conclusao? pelo que deu para ver neste simples teste, parece que:

  1. Todos os dados sao armazenados em memoria
  2. OU ha um buffer onde os dados ficam, e caso ele encha, ai sim o sistema pede mais dados para o db.

Nao sei, sao suposicoes.

Rafael

Antes de qualquer coisa, gostaria de agradecer pela atenção…

Irei testar algumas das opções postadas… realmente o assunto é mais complicado do que imaginei, mas com certeza há solução.

Assim que eu comprovar alguma das possibilidades volto aqui pra deixar o meu parecer.

Grato a todos!!! :smiley:

Alexandre (J2Alex)