Qual a estratégia menos ruim: lista estatica ou na session?

5 respostas
rogerio.alcantara

Boa tarde ninjas do GUJ, tudo bom?

Tenho uma situação que estou em dúvida qual a melhor estratégia usar e gostaria da opinião de vcs. Explico:

Cenário: Java6, VRaptor3, Hibernate3, Jboss.

Causo: Preciso exibir produtos na minha home de forma aleatória. Mas são muitos itens (+ de mil) e podem crescer mais e mais.

Como acho para esse caso a paginação do hibernate onerosa, pensei em fazer a paginação no lado do server. Segue o pseudo algoritmo:

1 - busco todos os produtos registrados por ordem de data.

2 - guardo essa lista na sessão;

Em seguida sempre que alguém solicitar a última lista de itens via ajax (normalmente de 10 em 10, pro html ficar leve);

1 - recupero a lista de produtos da sessão;

2 - recupero o ultimo index da lista de produtos da sessão. (se não existir, determino como sendo zero);

3 - faço listaDeProdutosDaSessão.sublist(index, 10);

4 - altero o index do inicio da lista (index +=10) e guardo o novo index na sessão;

5 - tenho uma verificação onde, quando percebo que cheguei ao final da lista, recarrego toda a lista de produtos do banco de dados novamente //isso é importante, para trazer novos itens.

Minha dúvida é:

Para esse cenário, qual é a estratégia menos ruim?

a: guardar a lista e index na sessão, como eu já estou fazendo.

ou b: fazer uma lista e index statico?

O que vcs acham/sugerem?

Espero ter conseguido explicar minha dúvida.

Agradeço antecipadamente.

5 Respostas

E

Rogerio…

Porque vc precisa trazer todos os itens do banco? Porque não paginar diretamente a consulta no banco trazendo por exemplo do banco de 10 em 10 conforme solicitado na tela?

Essa seria a melhor pratica.

rogerio.alcantara

Olá Emersson, tudo bom? Muito obrigado pelo retorno.

Cara, o problema é que são muitos itens (mais de 1000) e vai crescer e crescer…

O problema de fazer a paginação usando o hibernate (usando o setfirstresult/setmaxresults) é que, acompanhando pelo log do hibernate, percebi que ele faz um select * from table para depois paginar. O problema é que isso ocorre a cada requisição… =/

Pensei em fazer a paginação manualmente no lado do server, para evitar essa ida ao banco a todo momento. Principalmente nos cenários de múltiplos acessos simultâneos.

O que vc acha?

fabim

Quando vc disse:

“busco todos os produtos”

Ja ficou claro que nao esta implementando uma paginacao REAL. Entao seria melhor usar a paginacao que ja existe no hibernate ou EJB3 dá no mesmo.

Se vc quiser implementar uma paginacao real, BUSCANDO poucos registros dentro de um range (ex: 20) entao pode variar, no oracle temos o ROWNUM, no MySQL temos o LIMIT por ai vai…

Mas o que vc mais precisa pensar é: será que existe a necessidade de eu trazer mais de 100 resultados pro meu cliente?
O que percebo geralmente é nego se matando com paginacao, sendo que o usuario NAO VAI ficar buscando, clicando pra paginar num resultado grande (+ de 100).
Ele vai refinar a consulta.

Entao nunca trabalhe com resultSets grandes, induza seu usuario a refinar ate que o universo de resultados seja “trabalhável”.

rogerio.alcantara

Olá Fabim, muito obrigado pelo retorno.

Com certeza, concordo inteiramente com vc em caso de filtros e busca. Mas o meu cenário é diferente. Vou tentar explicar melhor:

A minha necessidade é exibir 10 em 10 produtos aleatórios a cada requisição.

Então vamos simular:

1 - Usuário A acessa a página: exibo produto 1, 2, 3;

2 - Usuário B acessa a página: exibo produto, 4, 5, 6;

3 - Usuário A dá um refresh na págna: exibo o produto 7, 8, 9;

E assim por diante.

Além disso, quando chega ao final na lista de 3 itens (estou usando jcarrossel) eu faço uma nova requisição (via ajax) buscando os próximos 3 itens. Ou seja:

4 - Usuário A ainda está na página e lista chegou ao final do jcarrossel: busco e exibo produto, 10, 11, 12.

Ou seja, nem é uma busca, é apenas exibição aleatória mesmo.

Espero ter ficado mais claro agora.

O que vc acha?

E

olá, me corrijam se eu estiver errado, mas que eu saiba, o JDBC utiliza um cursor dentro do sgbd para trazer os resultados, então, se você faz um select * from tabela pelo hibernate, e coloca o first para 100 e last para 200, ele vai marcar nas consultas ativas o select * from tabela, mas vai trazer para o cliente somente os 100 registros marcados pelo cursor.

Outra coisa, sobre a lista, se você está usando hibernate com cache, não precisa se preocupar com guardar os objetos, apenas manda ele buscar pelo id. Guarda e sorteia os ids que você quer com a lógica que vc quiser, e manda o hibernate buscar os id’s específicos, não precisa guardar uma lista de produtos para fazer o random. (o problema disso é que você teria que implementar uma lógica que buscasse os que foram apagados, mas isso não seria problema)

E se puder, cria um conjunto menor de objetos para fazer o random neles, assim você vai ter quase todos os objetos no cache do hibernate.

Criado 17 de novembro de 2011
Ultima resposta 17 de nov. de 2011
Respostas 5
Participantes 4