Tags: JSP - Struts 2 - AJAX - struts-dojo-tags
Considerando que você tenha uma tela com campos de filtragem, uma tabela (usando displaytags e AJAX) com os resultados da busca e essa busca seja relacionada a uma tabela com muitos registros.
Quando a tela for acessada, como nenhum filtro foi especificado, todos os registros da base de dados vão ser mostrados na tabela e isso pode demorar muito.
Para evitar esse problema você pode mostrar a tabela vazia e deixar parar mostrar os resultados somente depois que o botão de Busca seja acionado.
Na verdade a solução deste problema não está no diplaytags, mas sim na tag "div" do struts-dojo-tags onde a tabela é apresentada.
A tag fica assim:
<sx:div showLoadingText="true"
id="gridDivId"
href="seusistema/SuaAction"
theme="ajax"
listenTopics="show_grid"
formId="frm_demo"
executeScripts="true"
preload="false">
Preencha os campos do filtro e depois clique no botão Buscar
</sx:div>
O pulo do gato aqui é a propriedade "preload", que tem o valor default true. Quando ela é true, ela aciona imediatamente a ajax linkado com a tabela displaytags que realiza a busca.
O texto dentro da tag div será apresentado no lugar reservado à tabela quando a tela for acessada.
Referência:
[1] http://struts.apache.org/2.0.14/docs/dojo-div.html
Dicas de programação. A idéia é ir postando as soluções dos problemas que enfrento diariamente no desenvolvimento de software. Como minha memória é muito volátil, essa é a maneira que encontrei de lembrar de como resolvi cada problema. Quem sabe, de quebra, não acabo ajudando outras pessoas?
quarta-feira, 12 de janeiro de 2011
terça-feira, 11 de janeiro de 2011
Como limitar o número de registros retornados em uma consulta SQL
Tags: SQL, Ansi SQL, TOP, LIMIT, ROWNUM, Oracle, SQL Server
Não existe uma instrução SQL padronizada para limitar o número de registros retornados em uma consulta, ou seja, cada fornecedor implementa essa funcionalidade do seu jeito.
Veja um resumo de como fazer isso para alguns fabricantes:
Referências:
http://stackoverflow.com/questions/595123/is-there-an-ansi-sql-alternative-to-the-mysql-limit-keyword
http://www.macoratti.net/d250102.htm
http://www.dougboude.com/blog/1/2006/06/Equivalent-of-SQL-TOP-X-in-Oracle.cfm
Não existe uma instrução SQL padronizada para limitar o número de registros retornados em uma consulta, ou seja, cada fornecedor implementa essa funcionalidade do seu jeito.
Veja um resumo de como fazer isso para alguns fabricantes:
DB2 -- select * from table fetch first 10 rows only
Informix, InterBase/Firebird, SKIP -- select first 10 * from table
Microsoft SQL Server and Access -- select top 10 * from table
MySQL, PostgreSQL, SQLite, HSQL/H2 -- select * from table limit 10
Oracle -- select * from table where rownum <= 10
Referências:
http://stackoverflow.com/questions/595123/is-there-an-ansi-sql-alternative-to-the-mysql-limit-keyword
http://www.macoratti.net/d250102.htm
http://www.dougboude.com/blog/1/2006/06/Equivalent-of-SQL-TOP-X-in-Oracle.cfm
sexta-feira, 7 de janeiro de 2011
Como externalizar o persistence.xml
Tags: Java 6 - JEE - Spring 2.5 - Hinernate 3.0
No persistence.xml é possível configurar, entre outras coisas, a conexão com a base de dados.
Quando o sistema é entregue ao cliente em um jar ou war, não existe uma maneira trivial de alterar as informações da base de dados, como a string de conexão, o username e o password.
Para fazer isso o cliente precisaria abrir o jar/war, alterar o persistence.xml e remontar o archive. Como nem sempre o cliente tem um time que saiba fazer isso, pode ser que você queira deixar o persistence.xml fora da pasta META-INF do seu projeto, por exemplo, em um folder de configuração do sistema em qualquer lugar do file system.
Abaixo segue o trecho a ser configurado no applicationContext.xml:
<beans ...>
<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>file:///${CONF_FOLDER}/dataSource.properties</value>
</list>
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="file:///${persistence.path}"/>
<property name="persistenceUnitName" value="persistence-unit"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<context:annotation-config />
<context:component-scan base-package="br.com.seupackage.*"/>
</beans>
O pulo do gato aqui é a propriedade persistenceXmlLocation do LocalContainerEntityManagerFactoryBean. Com ela você pode especificar que o persistence.xml estará em qualquer lugar do .jar ou do file system [1].
Para não deixar o caminho do persistence.xml hardcoded e como não é possível usar variável de ambiente nessa propriedade, é possível utilizar o PropertyPlaceholderConfigurer para configurar esse path.
O arquivo dataSource.properties, que está no folder reprensentado pela variável de ambiente ${CONF_FOLDER}, tem a propriedade persistence.path com o caminho absoluto do persistence.xml.
O problema estaria resolvido aqui se não fosse um efeito colateral de mudar o persistence.xml de lugar. Quando o persistence.xml não está dentro do jar, o PU root path muda para o jar que iniciou o sistema.
Se o ponto de entrada do sistema é o jar que possuía o persistence.xml (java -jar seuSistema.jar), não tem problemas.
Caso o jar ponto de entrada do sistema chame outro jar que é o que possuía o persistence.xml, aí você terá que fazer uma modificação no persistence.xml
Um exemplo dessa arquiterura é:
projeto_gui.jar - ponto de entrada do sistema
projeto_model.jar - possui o applicationContext e o persistence
Veja a modificação no persistence.xml:
<persistence ...>
<persistence-unit name='persistence-unit'>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jar-file>file:///C:/seusistema/lib/projeto_model.jar</jar-file>
<properties>
...
<property name="hibernate.connection.provider_class"
value="org.hibernate.connection.C3P0ConnectionProvider" />
...
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@192.168.0.2:1521:base" />
</persistence-unit>
</persistence>
A tag <jar-file> foi adicionada para informar que o PU root path (o caminho que este persistence unit deve procurar as classes anotadas como Entity) é o jar que possuía o persistence.xml antes desta alteração.
Referência:
[1] LocalContainerEntityManagerFactoryBean: http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html#setPersistenceXmlLocation(java.lang.String)
No persistence.xml é possível configurar, entre outras coisas, a conexão com a base de dados.
Quando o sistema é entregue ao cliente em um jar ou war, não existe uma maneira trivial de alterar as informações da base de dados, como a string de conexão, o username e o password.
Para fazer isso o cliente precisaria abrir o jar/war, alterar o persistence.xml e remontar o archive. Como nem sempre o cliente tem um time que saiba fazer isso, pode ser que você queira deixar o persistence.xml fora da pasta META-INF do seu projeto, por exemplo, em um folder de configuração do sistema em qualquer lugar do file system.
Abaixo segue o trecho a ser configurado no applicationContext.xml:
<beans ...>
<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>file:///${CONF_FOLDER}/dataSource.properties</value>
</list>
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="file:///${persistence.path}"/>
<property name="persistenceUnitName" value="persistence-unit"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<context:annotation-config />
<context:component-scan base-package="br.com.seupackage.*"/>
</beans>
O pulo do gato aqui é a propriedade persistenceXmlLocation do LocalContainerEntityManagerFactoryBean. Com ela você pode especificar que o persistence.xml estará em qualquer lugar do .jar ou do file system [1].
Para não deixar o caminho do persistence.xml hardcoded e como não é possível usar variável de ambiente nessa propriedade, é possível utilizar o PropertyPlaceholderConfigurer para configurar esse path.
O arquivo dataSource.properties, que está no folder reprensentado pela variável de ambiente ${CONF_FOLDER}, tem a propriedade persistence.path com o caminho absoluto do persistence.xml.
O problema estaria resolvido aqui se não fosse um efeito colateral de mudar o persistence.xml de lugar. Quando o persistence.xml não está dentro do jar, o PU root path muda para o jar que iniciou o sistema.
Se o ponto de entrada do sistema é o jar que possuía o persistence.xml (java -jar seuSistema.jar), não tem problemas.
Caso o jar ponto de entrada do sistema chame outro jar que é o que possuía o persistence.xml, aí você terá que fazer uma modificação no persistence.xml
Um exemplo dessa arquiterura é:
projeto_gui.jar - ponto de entrada do sistema
projeto_model.jar - possui o applicationContext e o persistence
Veja a modificação no persistence.xml:
<persistence ...>
<persistence-unit name='persistence-unit'>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jar-file>file:///C:/seusistema/lib/projeto_model.jar</jar-file>
<properties>
...
<property name="hibernate.connection.provider_class"
value="org.hibernate.connection.C3P0ConnectionProvider" />
...
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@192.168.0.2:1521:base" />
<property name="hibernate.connection.username" value="user" />
<property name="hibernate.connection.password" value="password" />
</properties></persistence-unit>
</persistence>
A tag <jar-file> foi adicionada para informar que o PU root path (o caminho que este persistence unit deve procurar as classes anotadas como Entity) é o jar que possuía o persistence.xml antes desta alteração.
Referência:
[1] LocalContainerEntityManagerFactoryBean: http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html#setPersistenceXmlLocation(java.lang.String)
Assinar:
Postagens (Atom)