[Logo] Mentawai Forum - Mentawai Web Framework
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
DBListData  XML
Forum Index -> Comentários Gerais Go to Page: 1, 2 Next 
Author Message
andredelorme



Joined: 20/07/2005 11:41:46
Messages: 51
Offline

Pessoal,

Criei uma classe para ler listas de um banco de dados, gostaria da opinião de vocês. Críticas e sugestões serão bem vindas.

Code:
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import org.mentawai.db.ConnectionHandler;
 import org.mentawai.list.ListData;
 import org.mentawai.list.ListDataItem;
 
 /**
  *
  * @author delorme
  */
 public class DBListData implements ListData {
     
     String table;
     String idColumn;
     String descriptionColumn;
     int size = 0;
     
     ArrayList listLocales = new ArrayList();
     
     /** Creates a new instance of DBListData */
     public DBListData(ConnectionHandler connHandler, String table, String idColumn, String descriptionColumn) {
         this.table = table;
         this.idColumn = idColumn;
         this.descriptionColumn = descriptionColumn;
         
         try {
             Connection conn = connHandler.getConnection();
             String sql = "SELECT DISTINCT COUNT(" + idColumn + ") AS size FROM " + table;
             PreparedStatement pstmt = conn.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery();
             if (rs.next()) {
                 size = rs.getInt("size");
             }
             rs.close();
             pstmt.close();
             
             sql = "SELECT " + idColumn + ", " + descriptionColumn + ", locale FROM " + table;
             pstmt = conn.prepareStatement(sql);
             rs = pstmt.executeQuery();
             while (rs.next()) {
                 DBListDataItem item = new DBListDataItem(rs.getInt(idColumn), rs.getString(descriptionColumn), rs.getString("locale"));
                 listLocales.add(item);
             }
             rs.close();
             pstmt.close();
             connHandler.release(conn);
         } catch (SQLException sqle) {
 
         }
     }
     
     public java.util.List getValues(java.util.Locale locale) {
         ArrayList list = new ArrayList();
         for (int i = 0; i < listLocales.size(); i++) {
             if ( ((DBListDataItem)listLocales.get(i)).getLocale().equals(locale.toString()) ) {
                 list.add(listLocales.get(i));
             }
         }
         return list;
     }
     
     public String getValue(int param, java.util.Locale locale) {
         ArrayList list = new ArrayList();
         for (int i = 0; i < listLocales.size(); i++) {
             if ( ((DBListDataItem)listLocales.get(i)).getLocale().equals(locale.toString()) ) {
                 list.add(listLocales.get(i));
             }
         }
         return ((ListDataItem)list.get(param)).getValue();
     }
     
     public int size() {
         return size;
     }
     
     public String getName() {
         return "db" + table.substring(0, 1).toUpperCase() + table.substring(1);
     }
     
     
     
 }
 


Extensão do ListDataItem:
Code:
 import org.mentawai.list.ListDataItem;
 
 /**
  *
  * @author delorme
  */
 public class DBListDataItem extends ListDataItem {
     
     private String locale;
     
     /** Creates a new instance of DBListDataItem */
     public DBListDataItem(int id, String value, String locale) {
         super(id, value);
         this.locale = locale;
     }
     
     public String getLocale() { return locale; }
 }
 
 


Adição no ApplicationManager:
Code:
     public void loadLists() throws IOException {
         ListManager.init();
         
         DBListData categoria = new DBListData(connHandler, "categoria", "id", "descricao");
         ListManager.addList(categoria);
 
         DBListData situacao = new DBListData(connHandler, "situacao", "id", "descricao");
         ListManager.addList(situacao);
     }
 


Utilização:
Code:
 Situação: <mtw:select name="id_situacao" list="dbSituacao" />
 Categoria: <mtw:select name="id_categoria" list="dbCategoria" />
 


André Delorme
saoj



Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline

Bem legal André !!!!

Ainda nao voltei de viagem, mas quando chegar vou dar uma olhada com calma.

Se for o caso, podemos até adicionar isso ao framework.

Acho que vou criar uma conta de commiter pra vc !!!

Abraço,


Sergio Oliveira

andredelorme



Joined: 20/07/2005 11:41:46
Messages: 51
Offline

Sem problemas, não se preocupe. Quando tiver tempo análise e faça suas considerações.

Quanto a conta, ainda estou comçando, minhas contribuições são pequenas, mas pretendo ajudar sempre que possível.

Um abraço.


André Delorme
boaglio


[Avatar]

Joined: 28/09/2005 11:05:16
Messages: 299
Location: Sao Paulo - Brazil
Offline


Muito bom André!

Eu adaptei a sua solução para a minha aplicação, pois eu uso o QueryManager que isola os SQLs em um arquivo properties.

Code:
 public class DBListData  extends AbstractDAO implements ListData {
 
     String query;
     String name;
     String idColumn;
     String descriptionColumn;
     int size = 0;
     ArrayList listLocales = new ArrayList();
 
 	private static Logger logger = Logger.getLogger(DBListData.class);
 
 	/*
 	 * Construtor que define pt_BR como locale padrao
 	 */
 	public DBListData(String name,String query, String idColumn, String descriptionColumn){
 
 		this(name,query,idColumn,descriptionColumn,"pt_BR");
 	}
 
 	/*
 	 * Rotina principal
 	 */
     public DBListData(String name,String query, String idColumn, String descriptionColumn,String locale) {
         this.query = query;
         this.name = name;
         this.idColumn = idColumn;
         this.descriptionColumn = descriptionColumn;
 
         logger.info("Carregando lista = "+name);
 		Statement stmt = null;
 		DAOManager dao = DAOManager.getInstance();
 		Connection conn = dao.getConexao();
 		ResultSet rs = null;
         try {
             Connection conexao = dao.getConexao();
             stmt = super.createStatement(conexao);
             rs = stmt.executeQuery(super.getQuery(query));
             while (rs.next()) {
                 DBListDataItem item = new DBListDataItem(rs.getInt(idColumn), rs.getString(descriptionColumn), locale);
                 listLocales.add(item);
             }
             size = listLocales.size();
             logger.info("lista carregada = "+size+" registros");
 		} catch (SQLException e) {
 			logger.error("[ERRO DE SQL DO DBListData]:" + e.getMessage());
 		} catch (Exception e) {
 			logger.error("[ERRO DO DBListData]:", e);
         } finally {
             close(rs);
             close(stmt);
             close(conn);
         }
     }
 
     public java.util.List getValues(java.util.Locale locale) {
         ArrayList list = new ArrayList();
         for (int i = 0; i < listLocales.size(); i++) {
             if ( ((DBListDataItem)listLocales.get(i)).getLocale().equals(locale.toString()) ) {
                 list.add(listLocales.get(i));
             }
         }
         return list;
     }
 
     public String getValue(int param, java.util.Locale locale) {
         ArrayList list = new ArrayList();
         for (int i = 0; i < listLocales.size(); i++) {
             if ( ((DBListDataItem)listLocales.get(i)).getLocale().equals(locale.toString()) ) {
                 list.add(listLocales.get(i));
             }
         }
         return ((ListDataItem)list.get(param)).getValue();
     }
 
     public int size() {
         return size;
     }
 
 	public String getName() {
 		return name.toUpperCase();
 	}
 
 }
 
 


Aí pra criar as listas eu uso esse código:

Code:
    public void loadLists() throws IOException {
         ListManager.init();
         DBListData usuarios = new DBListData("USUARIOS","usuario.trazLista", "user_id", "username");
         ListManager.addList(usuarios);
     }
 
 

http://www.boaglio.com
[WWW]
boaglio


[Avatar]

Joined: 28/09/2005 11:05:16
Messages: 299
Location: Sao Paulo - Brazil
Offline


Sérgio,

O resultado de uma DBListData fica em cache?

Se sim, existe uma maneira de desabilitar isso?

Eu notei na minha aplicação na Locaweb, eu cadastro valores
novos, mas eles não aparecem nos combos.




http://www.boaglio.com
[WWW]
saoj



Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline

Quem fez o DBListData foi o Andre, mas o comportamente certo é cachear em memória mesmo, pois vc nao quer ficar lendo isso toda hora...

O que vc pode fazer é criar uma função para reload e chamá-la de um JSP.

Sergio Oliveira

andredelorme



Joined: 20/07/2005 11:41:46
Messages: 51
Offline

Fernando,

Já havia visto isso, o que podemos fazer é alterar os métodos da Interface ListData para trazer os dados diretamente do banco, sempre.

Além do “custo” maior, a minha preocupação é que, podemos chamar o método size() que retornará um valor, e depois executamos uma iteração na lista chamando o método getValue(), se durante esse processo o banco for modificado, o resultado será incorreto.

Estou certo, Sergio? Tem alguma sugestão?
Talvez a tag html select devesse ser modifica para utilizar apenas um método que retorna a lista (ou uma array) e a partir desta lista “descobrirmos” o tamanho (size).


André Delorme
saoj



Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline

Verificar a cada chamada se precisa recarregar do banco é muito custoso.

O ideal é colocar um timeout para checagem no banco, mas a request que pegar o timeout pode demorar bastante chateando o usuário.

Acho que a melhor solução é fazer o recarregamento através de um método estático que pode ser chamado por um JSP...


Sergio Oliveira

boaglio


[Avatar]

Joined: 28/09/2005 11:05:16
Messages: 299
Location: Sao Paulo - Brazil
Offline


Seria ideal (pra mim) que a tag SELECT tivesse uma opção reload,
com as opções:

padrão (faz cache):

Code:
   <mtw:select name="app_id" list="APLICACOES" />
   ou 
   <mtw:select name="app_id" list="APLICACOES" reload="once"/>
 


outra opção (não faz cache) :

Code:
   <mtw:select name="app_id" list="APLICACOES" reload="always"/>
 


O que eu precisaria alterar no código para fazer isso?

http://www.boaglio.com
[WWW]
guipx


[Avatar]

Joined: 23/11/2005 22:57:23
Messages: 3
Offline

ai.. achei muito interessante... e to usando

queria saber se tem como por exemplo:
a lista é assim independente de onde ela vem

1-SP
2-MG
3-SC
4-PR

<mtw:select nome="estados" list="lista_do_banco"/>

e queria escollher qual registro vem selecionado
por exemplo
<mtw:select nome="estados" list="lista_do_banco" selected="3"/>
selecionaria SC

acho que deu pra entender né
boaglio


[Avatar]

Joined: 28/09/2005 11:05:16
Messages: 299
Location: Sao Paulo - Brazil
Offline


Dentro do código da sua action faz assim:

Code:
 output.setValue("estados", "3");
 

http://www.boaglio.com
[WWW]
pauloperes


[Avatar]

Joined: 07/11/2005 13:56:45
Messages: 41
Offline

Dae galera,

Bom estou meio perdido quanto a internacionalização, vejam, na minha aplicação tenho uma tabela de generos de usuario, onde tenho tres campos, onde o usuario escolhe um na hora de seu cadastro. A minha dúvida é tenho que ter é como implementar isto com internacionalização, se tenho que ter uma tabela para cada idioma?

Valeu,

Paulo
[Email] [MSN]
andredelorme



Joined: 20/07/2005 11:41:46
Messages: 51
Offline

pauloperes,

Para utilizar a classe DBListData, que criei, basta que sua tabela contenha um coluna para identificador (PK) e outra com a descrição. O nome desses campos serão passados para a classe, assim como o nome da tabela.
Além disso, é preciso que na tabela exista um compo de nome locale, que será utilizado para a internacionalização.

Entendeu?

Analise o código que postei aqui que não nada complicado, e pode até ser melhorado.


André Delorme
pauloperes


[Avatar]

Joined: 07/11/2005 13:56:45
Messages: 41
Offline

André,

Já olhei sim, porém veja, na minha tabela, eu tenho mais campos, id(pk), nome_genero e idade_minima.

Kra, to meio devagar ainda no assunto, a pergunta é besta, mas onde eu coloco todas mensagens em três idiomas na tabela, no campo locale?

Valeu,

Paulo
[Email] [MSN]
andredelorme



Joined: 20/07/2005 11:41:46
Messages: 51
Offline

Paulo,

Você quer criar uma combo com os possíveis generos?

Para isso no ApplicationManager adicione:
Code:
     public void loadLists() throws IOException {
         ListManager.init();
         
         DBListData generos = new DBListData(connHandler, "nome_tabela", "id", "nome_genero");
         ListManager.addList(generos);
 
     }
 


Além disso será necessário adicionar uma coluna chamada locale, e a PK deverá ser id+locale, com isso você irá incluir um registro para cada idioma.

Ajudei?


André Delorme
 
Forum Index -> Comentários Gerais Go to Page: 1, 2 Next 
Go to:   
Powered by JForum 2.1.6 © JForum Team