Buscar dados diretamente no banco ou usar List?

Gente tenho uma janela onde vou navegar pou varios registros, estou com dúvida na implementação, pois não sei se pucho todos dados e guardo em uma List ou se vou usando rs.next() e sempre pelo banco!

Tipo como vão ser multiplos usuários usando um banco, dae com o list eu teria sempre q atualizar essa List, mas usar o rs.next() eu também iria no banco a toda além de ficar uma implementação mais feia!
Alguém tem alguma sugestão??

A cada pagina, faria select buscando somente a pagina de registros que quero.

Geralmente os bancos implementam recursos do tipo:

  • traga x primeiras linhas
  • traga as linhas onde linha esta entre x e y

Então faria uma calculo simples da pagina que preciso.
dado que cada pagina possui 10 linhas, a paginacao seria algo como:

select top 10 *
from tabela
where row_num() between 1 and 10

Esta é a forma mais robusta de se implementar paginação.

qual o banco utiliza?

O SGBD é o postgree, mas acho q você não me entendeu, ou eu q não te entendi, tipo eu pensei em ir pegando usando um if(rs.next()){…} ou ir puxando listas e fazendo updates nas listas e andando nas listas!

Sem dúvidas colocar em um List.
Senão além de sobrecarregar o banco, sobrecarrega a rede também.

Geralmente a melhor prática é alocar recursos, fazer a consulta, fechar recursos.
Isso evita um tanto de problema, dentre os quais locks de banco.

Quando voce mantem um resultset aberto, voce esta segurando recurso de banco desnecessariamente.
Em uma aplicação profissional utilizada por muitos usuarios ao mesmo tempo, isso vai acabar em ‘caca’

Então reforço.
Abra a conexao (ou utilize um pool)
abra o resultset e busque a pagina
feche o resultset
libere a conexao
entregue os dados para a tela.

quando o cliente atualizar, ele chama o botao gravar…
e voce faz a atualizacao, podendo ser item por item ou batch statement, o que eh melhor

Para buscar paginas em postgrees

SELECT column FROM table
LIMIT 10 OFFSET 10

Fonte:
http://www.petefreitag.com/item/451.cfm

Carregar na list inteira, você vai carregar muitos dados, que talvez não sejam utilizados.

Se possui 100 paginas e o usuario quer ver apenas a pagina 1 , voce vai carregar outras 99.

E se em seu navegador, der a opcao do usuario ir para a pagina x … voce pode buscar exatamente ela.

Seu software ficará rápido, robusto e consumirá pouco recurso de rede e de cliente.

Humm, olhe a minha lógica!

Tipo também penso ser melhor dessa forma, mas acho que ainda estou pensando de uma maneira meio arcaica!

eu faço o seguinte eu tenho a minha classe “ContaDAO” que tem um metodo de retornar toda a tabela do banco e gerar uma List com os dados dela!

eu ia comparar a minha lista atual que estava na execução com essa lista que eu ia puxar toda vez que eu andasse pra frente ou pra traz na tela, dae eu ia ver se o numero de registros da list que eu puxei fosse menor que a atual eu saberia que tem alguem que foi excluido, se fosse maior, alguem que foi adicionado, e se fosse igual ainda teria que ver se algum dado foi atualizado, tem alguma sugestão de implementação menos grosseira??

Obrigado! :wink:

Eh desktop a aplicação!

ok. Tenho várias sugestões :slight_smile: me desculpe a franqueza, mas realmente está muito grosseira esta implementação.

Sempre que implementar, pense em: performance, tráfego de rede , carga no cliente e carga no servidor. Você deve evitar tudo que cause problemas destes tipos.
Por exemplo, carregar a lista inteira da tabela causará carga no servidor e/ou cliente excessiva (alto consumo de memoria) e alto trafego de rede. Então não é uma estratégia boa. Pense se a tabela tivesse 2 milhões de registro, seu software sobreviveria?

Vou te sugerir o seguinte:
1 - implemente um dao que busque por pagina e ponto. Supondo que seja lista de fornecedores:
List dao.buscarFornecedores(filtro, pagina);
Neste metodo voce aplica a dica do postgrees limit e offset

2 - No objeto Fornecedores ou em algum que ele extenda, coloque um atributo enum. Ex.: [Nao Alterado], [Alterado], [Excluido]
Mostre a lista na tela, na pagina que o usuario solicitou. Se ele alterar o registro, marque a enum alterado.
Se ele clicar em apagar o registro, marque a enum como excluido.

3- Quando o cliente clicar em Gravar, percorra a lista … quando encontrar objeto Fornecedor com enum = Alterado , faça update.
Quando encontrar enum = Excluido, exclua o registro.

4- Se o cliente for para a proxima pagina, volte ao item 1.

Se voce quer que o usuario clique em gravar somente apos alterar tudo que ele quer em várias páginas, você ainda pode usar esta técnica. sera apenas mais trabalhoso.

Ok, pra ser bem franco não entendi muito bem, é que esta é a minha primeira implementação de verdade, o primeiro sistema GRANDE que estou desenvolvendo, ainda estou na em curso da faculdade :wink:

Duvidas:

1ª - O que seria o limit e o offset do postgree?

2ª - Na parte do enum tipo como eu iria alterar nas telas de todos computadores da sala e não só da minha tela? Pois se eu usar o enum ele iria alterar na lista atual onde eu estou usando certo? eu não teria q informar isso ao banco e depois todos outros computadores usarem esta informação atualizada?

Vlw pela força amigo!

O limite é o número de registros que irão vir.

E o offset é um índice, digamos assim.

Se, antes a consulta retornava 100 registros, agora irá retornar a partir do offset até o limit.

Não sei se fui claro, tentei. :s

Sim sim, mas essa foi soh a primeira duvida :wink:

Alguem pode me ajudar com a segunda :stuck_out_tongue:

Boa tarde a todos.

Sinceramente não acho uma boa voce carregar uma lista paginada e fazer alterações em cache de disco, quando voce pode fazê-la de forma direta via SQL, a não ser é claro quando o volume de dados de sua empresa seja gigantesco.

Caso contrário, pense no tráfego de dados (Select para consultar e Insert, Delete e Update para alterar os dados, somente), no segundo caso, voce pode fazer uma ação direta via SQL, sem precisar carregar ResultSet no disco ou fazer algo parecido, e no primeiro voce utilize um List para consultar dados paginados, populando até um JTable, ou se for Web project, uma tag <select></select> do html. O ResultSet é dividido em dois métodos com base neste tráfego de dados que são o “selectQuery” para consultar e “executeQuery” para alterar.

Analise com calma a modelagem de negócios do seu projeto e vê se vale a pena, carregar um conjunto de registros em cache de disco, só para alterar dados no Banco, enviando-os por pacote, o que poderia até reduzir a performance do sua aplicação.

Bom gente acho que o volume de dados não será tão grande, não tenho muita base, mas acho q menos de 20 pessoas vão ultilizar os dados e manejar no banco! Então o que acham q seria uma implementação menos grosseira e mais elegante e eficiente?

Gente tive a idéia de soh fazer a verificação do PROXIMO/ANTERIOR quando eu puchasse a List, ai não teria que atualizar toda ela sempre ganhando um tempo consideravél, certo?

Mas quando fui implementar na minha classe DAO teve o seguinte problema eu vou ter que saber em qual posição eu estou para pegar o próximo, mas como eu vou acessar a list que esta rodando la na frame que mostra os dados para o funcionario?

Vc poderia usar Hibernate e usar Lazy Evaluation.

Dessa forma vc pode iterar sobre objetos que são, na verdade, proxys que acessam o banco sob demanda utilizando os mecanismos de cache do Hibernate.

[quote=peczenyj]Vc poderia usar Hibernate e usar Lazy Evaluation.

Dessa forma vc pode iterar sobre objetos que são, na verdade, proxys que acessam o banco sob demanda utilizando os mecanismos de cache do Hibernate.
[/quote]

Brother vc falou grego cmg!! Só entendi a parte de “iterar”

E acho que o chefe naum vai libera pra mim trocar de SGBD agora.

PS.: aplicação desktop