O pureQuery é uma plataforma de acesso a dados de alto desempenho formada por ferramentas de desenvolvimento, uma® API de Java, um tempo de execução e serviços de monitoramento. Usando a API leve de pureQuery, é possível escrever um código de acesso a dados que acessa DB2, Informix e até mesmo bancos de dados Oracle. No entanto, vários dos benefícios do pureQuery como — a capacidade de visualizar e modificar a SQL gerada, o uso de boas práticas de acesso ao banco de dados, o suporte a recursos de desempenho como lotes heterogêneos e a capacidade de reunir dados de desempenho a partir de consultas — não requerem o uso da API. Para obter mais informações sobre pureQuery, consulte a seção Recursos .
Um caso de uso chave para utilizar o pureQuery com aplicativos já existentes pode ser observado nos servidores de dados de DB2, nos quais é possível converter o modo de execução de SQL da execução dinâmica (padrão para os aplicativos de Java) para a execução estática. Isso elimina a necessidade de preparação no tempo de execução e pode reduzir o risco de injeção de SQL. Para obter mais informações sobre os benefícios da execução estática, consulte a seção Recursos .
Com o pureQuery, também é possível aproveitar os recursos do Optim Development Studio — como visualizar métricas de desempenho e correlacionar as instruções SQL geradas ao código de origem de Java que as originou. Isso torna o pureQuery útil para o uso com aplicativos já existentes que acessam bancos de dados Oracle e Informix. A Figura 1 é uma captura instantânea do Optim Development Studio com alguns recursos chave ressaltados.
Figura 1. Visualização da estrutura de tópicos do Optim Development Studio
Para obter mais informações sobre o Optim Development Studio, consulte a seçãoRecursos .
Há duas formas de aproveitar o pureQuery com aplicativos já existentes que não foram escritos com a API do pureQuery. É possível usar esses métodos separados ou juntos:
- Use aotimização de cliente para fazer o Optim pureQuery Runtime capturar SQL (e os metadados associados de desempenho e aplicativos) enquanto o programa de Java está em execução. Essa abordagem é flexível, pois é possível usá-la com qualquer aplicativo de Java, inclusive aplicativos empacotados. Entretanto, requer configuração adicional e a execução de vários caminhos no código para assegurar que toda a SQL seja capturada. Depois que a SQL é capturada, é possível usar toda a capacidade do Optim Development Studio para modificar a SQL, visualizar os caminhos de acesso, fazer testes de desempenho e a análise de impacto. A seção Recursos contém um link para um tutorial que descreve como usar a otimização de cliente.
- Use módulos de integração para possibilitar que os programas aproveitem toda a capacidade do pureQuery e do Optim Development Studio sem necessidade de uma etapa inicial de captura. Esta é uma nova abordagem e é o foco dessa série de artigos. Com essa abordagem, o Integration Module extrai a SQL e os seus metadados antes da execução do programa de Hibernate/iBATIS. Anteriormente, esse suporte estava disponível para o WebSphere® OpenJPA (consulte a seção Recursos para obter um link para o artigo sobre esse assunto). Agora, com os novos módulos de integração, esse suporte também está disponível para aplicativos de Hibernate e iBATIS. Com esses módulos, é possível usar um conjunto de ferramentas para visualizar e otimizar a SQL sem fazer uma captura de tempo de execução (também é possível usá-la em conjunto com a captura, conforme o descrito em Usando a captura incremental para reunir consultas de Criteria.)
O IBM Integration Module para Hibernate e pureQuery possibilita os seguintes benefícios para os aplicativos de Hibernate:
- Os aplicativos de Hibernate podem usar SQL estática sem a necessidade da captura inicial de otimização de cliente do pureQuery. O Integration Module gera a SQL que pode ser usada pelo aplicativo de Hibernate. A SQL pode ser vinculada estaticamente para o acesso a bancos de dados de DB2 e pode ser revisada, compartilhada, otimizada e substituída sem alterar o aplicativo em si. A SQL também pode ser correlacionada ao código do aplicativo para rastrear problemas de desempenho até o código de origem do Hibernate ou às alterações de objetos de banco de dados para fazer a análise de impacto usando o Optim Development Studio.
-
Os seus aplicativos de Hibernate podem usar o recurso de lotes heterogêneos no pureQuery.
Esse recurso permite formar lotes de várias solicitações de
INSERT,UPDATEeDELETEaté mesmo quando fazem referência a várias tabelas. Por exemplo: a atualização de um objeto de funcionário que requer a atualização de várias tabelas de banco de dados que constituem o objeto pode ser feita em um único acesso ao banco de dados, e não em vários acessos. Cada roundtrip da rede ao servidor de banco de dados custa caro em termos de desempenho. Portanto, sob o ponto de vista do desempenho, é melhor ter menos roundtrips, mas lotes maiores. Esse suporte está disponível para bancos de dados de DB2 e Informix.
Este artigo descreve como configurar e usar o Integration Module para Hibernate e pureQuery. Primeiro, descreve o recurso de SQL estática do Integration Module e, em seguida, descreve o recurso de lotes heterogêneos. O artigo pressupõe que você tem algum conhecimento sobre o Hibernate e que está usando o Hibernate 3.2 ou posterior. É possível aproveitar os benefícios oferecidos pelo Integration Module sem alterar o código do aplicativo.
O que é SQL estática e como pode ajudar no desempenho?
A SQL estática no DB2 é um recurso poderoso que possibilita otimizar o acesso a dados no tempo de execução. Ela faz isso ao realizar parte do trabalho — como determinar o caminho de acesso ao banco de dados — antecipadamente. Isso ajuda a fazer o tempo de execução funcionar de forma mais rápida e consistente. A Figura 2 mostra uma comparação entre a execução da SQL dinâmica e da SQL estática.
Figura 2. Execução da SQL estática em comparação com a execução da SQL dinâmica
O modelo de segurança para a SQL estática também é diferente do modelo para a SQL dinâmica. Com a SQL estática, os usuários só recebem privilégios para executar a saída do processo de ligação, conhecido como pacote. Esse pacote contém as instruções SQL. Portanto, se todo o acesso a uma tabela é estático, bastaria dar acesso somente ao pacote, e não a toda a tabela ou visualização. Além disso, ao usar SQL estática você reduz a oportunidade de injeção mal intencionadaum risco à segurança bastante conhecido da SQL dinâmica.
Para obter mais informações sobre a SQL estática consulte a seção Recursos .
Visão geral da criação de SQL estática com o Integration Module para Hibernate e pureQuery
Esta seção compara a execução padrão de um aplicativo de Hibernate (SQL dinâmica) com uma execução que usa o Integration Module para criar e usar SQL estática.
Execução de SQL dinâmica pelo Hibernate: JDBC
A Figura 3 mostra a execução geral de um aplicativo de Hibernate sem o Integration Module. O Hibernate gera as cadeias de instrução SQL e as executa no banco de dados usando as operações "prepare" e "execute" de JDBC.
Figura 3. Execução de SQL dinâmica de um aplicativo de Hibernate sem o Integration Module
Execução de SQL estática pelo Hibernate com o Integration Module: pureQuery
A Figura 4 mostra a execução detalhada de um aplicativo do Hibernate com o Integration Module. Os pacotes do DB2 foram criados para a execução de SQL estática. A figura descreve o seguinte:
- Uma etapa de geração de SQL (
HibernateGen) reúne toda a SQL que o aplicativo de Hibernate usa em um arquivo XML de pureQuery (esses arquivos são do tipo .pdqxml). Em seguida, esse arquivo pode ser usado no Optim Development Studio para ajuste ou análise de impacto sem necessidade de uma etapa deBIND. O arquivo XML de captura do pureQuery pode ser ligado a pacotes estáticos com o Static Binder. - Durante a execução do aplicativo, o pureQuery Runtime redireciona as chamadas ao JBDC para executar os pacotes estáticos de DB2 que foram criados na etapa de geração. O arquivo pdq.properties controla o comportamento de execução do pureQuery Runtime (dinâmico ou estático) e também fornece a localização do arquivo XML do pureQuery.
Figura 4. Execução de SQL estática de um aplicativo do Hibernate com o Integration Module
Quais instruções SQL podem ser extraídas de um aplicativo do Hibernate?
As seguintes instruções SQL podem ser extraídas pelo Integration Module:
- SQL para consultas nomeadas — Java Persistence Query Language (JPQL) e Hibernate Query Language (HQL)
- SQL para consultas nomeadas nativas — consultas nomeadas SQL, Java Persistence API (JPA) e Hibernate API especificados
- SQL para operações de Create, Read, Update e Delete (CRUD) em Hibernate Beans/entidades — JPA e API nativa
- SQL para operações de CRUD em coleções em Hibernate Beans/entidades — JPA e API nativa
SQL para consultas de Criteria e consultas lineares não são geradas pelo Integration Module. Deve-se evitar incorporar consultas HQL no código Java a menos que sejam consultas realmente dinâmicas. Nesses casos, não é possível aplicar SQL estática a essas consultas. Para obter informações sobre a externalização de consultas HQL, consulte a seção Recursos .
O que são lotes heterogêneos e como podem ajudar no desempenho?
O Hibernate usa JDBC para o acesso a dados. O JDBC suporta uma forma de lote chamada lotes homogêneos. Essa forma de lote está restrita a tabelas únicas e a várias execuções da mesma instrução SQL, desde que a instrução tenha parâmetros de entrada. No entanto, ao atualizar vários tipos de entidade em uma transação ou usar mapeamento de entidades que envolvem tabelas secundárias, herança de junção ou herança de tabela por classe, uma transação pode conter várias instruções SQL envolvendo várias tabelas. Nesses casos, os lotes de JDBC não são efetivos.
Além disso, o lote de JDBC só suporta a adição de instruções SQL diferentes ao lote, desde que as instruções SQL não tenham parâmetros de entrada. No entanto, os aplicativos típicos que usam Hibernate (ou OpenJPA) usariam instruções SQL com parâmetros de entrada devido à característica dinâmica dos aplicativos. Nesses cenários, os lotes de JDBC não permitem lotes de instruções SQL diferentes.
Considere o cenário de lote mostrado na Lista 1.
Lista 1. Um cenário de lote
PreparedStatement pstmt = conn.prepareStatement("update T1 set name=? where id=?");
pstmt.setString(1,"name1");
pstmt.setInt(2,1);
pstmt.addBatch();
pstmt.setString(2,"name2");
pstmt.setInt(2,2);
pstmt.addBatch();
pstmt.executeBatch();
|
Não é possível adicionar a instrução SQL delete from T1 where ID = ?
ao lote mostrado na Lista 1.
Em vez disso, seria necessário criar outra preparedStatement
para a exclusão, e outra mensagem seria enviada ao servidor de banco de dados para preparar a instrução para a consulta de exclusão.
Talvez seja possível usar lotes heterogêneos, que estão disponíveis com o pureQuery, para melhorar o desempenho em situações que não estão cobertas pelos lotes de JDBC. Por exemplo: examine novamente o cenário mostrado na Lista1. Com o pureQuery, é possível adicionar as instruções SQL na Lista 2 ao mesmo lote de pureQuery. Em seguida, o pureQuery prepararia a instrução e enviaria todas essas instruções ao servidor de banco de dados em uma única mensagem. Isso pode melhorar o desempenho.
Lista 2. Lotes heterogêneos
update T1 set name=? where id=? delete from T1 where ID = ? |
A Tabela 1 resume algumas características dos programas que podem aproveitar os lotes heterogêneos do pureQuery.
Tabela 1. Cenários onde os lotes heterogêneos do pureQuery podem ser úteis
| Característica do programa | Suportado pelos lotes heterogêneos do JDBC? | Suportado pelos lotes heterogêneos do pureQuery? |
|---|---|---|
| Forma lotes das atualizações para entidades que se correlacionam a várias tabelas | Não | Sim |
| Forma lotes das atualizações com relação à mesma tabela, mas colunas diferentes | Não (a menos que esteja usando literais em vez de parâmetros de entrada) | Sim |
Forma lotes de várias operações (INSERT, UPDATE, DELETE) com relação à mesma tabela | Não (a menos que esteja usando literais em vez de parâmetros de entrada) | Sim |
| Forma lotes de atualizações com relação a várias entidades | Não (a menos que esteja usando literais em vez de parâmetros de entrada) | Sim |
Os lotes heterogêneos não fornecem uma melhora no desempenho do aplicativo nos seguintes cenários:
-
O aplicativo é formado somente por instruções
SELECT. Isso acontece porque os lotes heterogêneos na release atual do Integration Module só melhoram o desempenho de instruçõesINSERT,UPDATEeDELETE. - O aplicativo usa entidades com identidade de tabela ou geração de chaves de sequência de banco de dados.
Visão geral da habilitação de lotes heterogêneos com o Integration Module
Esta seção compara a execução de um aplicativo de Hibernate que usa os lotes heterogêneos do pureQuery a um aplicativo que não os usa.
Lotes padrão no Hibernate: JDBC
A Figura 5 mostra o fluxo geral de execução do exemplo de aplicativo de Hibernate sem os lotes heterogêneos do pureQuery.
(O exemplo de aplicativo está disponível na seção Download .)
O Hibernate gera cadeias de instruções INSERT, UPDATE e DELETE
e as passa para o perseverador de classe para execução.
O perseverador chama o processador de lotes para realizar as operações "prepare" e "execute" de JDBC.
Figura 5. Execução de um aplicativo de Hibernate sem os lotes heterogêneos do pureQuery
Lotes heterogêneos no Hibernate: pureQuery
A Figura 6 mostra o fluxo geral de execução do exemplo de aplicativo do Hibernate com lotes heterogêneos do pureQuery.
O Hibernate gera cadeias de instruções INSERT, UPDATE e DELETE
e as passa para o perseverador de classe para execução.
O IBM Integration Module implementa o processador de lotes, eventListener e as interfaces do perseverador para possibilitar que as instruções SQL INSERT, UPDATE e DELETE sejam roteadas para o pureQuery e não para o JDBC e aproveitem os lotes do pureQuery.
O FlushListener notifica o processador de lotes para executar o lote assim que todas as instruções SQL forem adicionadas ao lote a partir de uma transação.
A versão atual do Integration Module não suporta lotes heterogêneos de instruções SELECT , para que não passem pelo perseverador e processador de lotes personalizado.
Figura 6. Execução de um aplicativo Hibernate com lotes heterogêneos de pureQuery
Pré-requisitos para usar o IBM Integration Module para Hibernate e pureQuery
A seção Recursos contém um link que você pode usar para fazer o download do IBM Integration Module para Hibernate e PureQuery.
Para usar o pureQuery Integration Module, é necessário ter:
- Optim pureQuery Runtime 2.2.0.3 ou superior (Consulte a seção Recursos para ver o link para fazer o download de uma versão de avaliação de 30 dias do IBM Optim Development Studio e do Optim pureQuery Runtime. O tempo de execução deve estar na mesma máquina que o Optim Development Studio.)
- Certifique-se de que pdq.jar e pdqmgmt.jar estejam no caminho da classe.
- IBM Data Server Driver para JDBC e SQLJ 3.58 ou 4.7 (disponível com o Optim Development Studio) ou consulte a seção Recursos para ver o link para fazer o download).
- Hibernate 3.2 ou posterior.
O Integration Module contém um utilitário validador que pode ser usado para verificar os pré-requisitos. Consulte Use o utilitário versionValidator para verificar os pré-requisitos para ver as instruções de uso do utilitário.
O IBM Integration Module para Hibernate e pureQuery funciona quando o aplicativo está acessando qualquer um dos seguintes sistemas de banco de dados:
- DB2 para Linux®, UNIX®e Windows® V8.2, Fix Pack 11 ou posterior
- DB2 para Linux, UNIX e Windows V9.1, V9.5, ou V9.7
- DB2 para i V5R4 (somente recurso de lotes heterogêneos)
- DB2 para z/OS® V8 ou posterior
- Informix Dynamic Server V11.10 ou V11.5 (somente recurso de lotes heterogêneos)
Exemplo de aplicativo usado neste artigo
O arquivo DemoHibApp.zip na seção Download contém um exemplo de aplicativo que pode ser usado para experimentar o recurso caso você esteja usando o Hibernate 3.2 ou posterior.
Habilitando a SQL estática do pureQuery para aplicativos de Hibernate
Esta seção usa o exemplo de aplicativo de Hibernate para ajudar a explicar como o IBM Integration Module funciona para SQL estática.
Edite Provider em persistence.xml
Se você está usando persistence.xml, para habilitar o suporte a SQL estática do pureQuery, é necessário garantir que a propriedade de provedor esteja especificada em persistence.xml.
No exemplo de aplicativo, essa propriedade já está definida, como mostra a primeira linha da Lista 3.
Lista 3. Propriedade obrigatória em persistence.xml para habilitar a SQL estática do pureQuery
<provider>com.ibm.pdq.hibernate3.PDQHibernatePersistence</provider> <!-- <provider>org.hibernate.ejb.HibernatePersistence</provider> --> |
Se você está usando hibernate.cfg.xml, não é necessário alterá-lo.
Por que a alteração de Provider é obrigatória para possibilitar o uso de SQL estática com o Hibernate?
O uso de SQL estática exige que a cadeia de caractere SQL gerada pelo Hibernate seja exatamente a mesma a cada vez. Há um programa conhecido no Hibernate que faz com que o programa gere a mesma SQL, mas com aliases de coluna diferentes, ao longo do aplicativo. (Consulte este post do fórum no Web site do Hibernate para ver detalhes: como os nomes alternativos de colunas são gerados.)
Há duas formas de resolver esse problema para habilitar a SQL estática:
- Aplique o patch Hibernate Defect HHH-2448 ao Hibernate.
- Use as classes Configuration fornecidas pelo Integration Module.
O exemplo de aplicativo usa o Hibernate 3.2, o gerenciador de entidades e as anotações do Hibernate. Portanto, para compilar o aplicativo, é necessário que os seguintes arquivos JAR estejam no caminho da classe, junto com os outros arquivos JAR necessários para o Hibernate:
- hibernate3.jar
- hibernate-entitymanager.jar
- hibernate-annotations.jar
- hibernate-common-annotations.jar
- ejb3-persistence.jar
- dom4j-1.6.1.jar
- log4j-1.2.15.jar
- javassist-3.4.GA.jar
- antlr-2.7.6.jar
- commons-collections-3.1.jar
- slf4j-api-1.5.2.jar
- slf4j-log4j12-1.5.2.jar
- commons-logging-1.0.4.jar
- pdq-hibernate3.2.jar (vem com o Integration Module)
Para usar o IBM Integration Module, também é necessário que estes arquivos JAR estejam no caminho da classe:
- pdq.jar
- pdqmgmt.jar
- Os JARs de db2jcc
Use o utilitário versionValidator para verificar os pré-requisitos
O Integration Module contém um programa chamado versionValidator, que faz a verificação de pré-requisitos do caminho da classe referente à versão do Hibernate, driver do JDBC e pureQuery Runtime. A Lista 4 mostra o comando que executa o programa.
Lista 4. Comando para executar o programa versionValidator
java com.ibm.pdq.hibernate3.utility.VersionValidator |
Se os arquivos JAR incluídos no caminho da classe estiverem no nível correto, o programa versionValidator exibe mensagens semelhantes às mostradas na Lista 5.
Lista 5. Saída do programa versionValidator quando todos os pré-requisitos estão corretos
>set CLASSPATH=./pdq.jar;./pdqmgmt.jar;./hibernate3.jar;./db2jcc.jar;./pdqhibernate3.jar; >java com.ibm.pdq.hibernate3.utility.VersionValidator IBM integration module version: 2.2.0.3 Hibernate version: 3.3.1.GA Found pdqmgmt.jar PDQ runtime version: 2.18.121 IBM DB2 JDBC Universal Driver: 3.53 java version: 1.5.0_13 |
Se algum dos arquivos JAR incluídos no caminho da classe não estiverem no nível correto, o programa versionValidator mostra a mensagem de erro correspondente. Por exemplo: as mensagens da Lista 6 indicam que o driver de JDBC do DB2não está no nível correto para trabalhar com o Integration Module.
Lista 6. Saída do programa versionValidator com um pré-requisito incorreto
Hibernate version: 3.3.1.GA
Found pdqmgmt.jar
PDQ runtime version: 2.1.70
Found IBM DB2 JDBC Universal Driver version: 2.3 **** ERROR. Incorrect level. Requires
V3.53 or higher
java version: 1.5.0_13
|
Prepare o banco de dados do exemplo de aplicativo
Siga estas etapas para preparar o banco de dados do exemplo de aplicativo:
- Crie um banco de dados com o nome demodb. O Hibernate cria automaticamente as tabelas necessárias.
- Descompacte o arquivo DemoHibApp.zip e importe o exemplo de aplicativo como um projeto Java para a área de trabalho do Optim Development Studio.
- Inclua os mesmos arquivos JAR listados em Configure o caminho da classe no caminho de construção do projeto. É possível adicionar os arquivos JAR do pureQuery e do IBM Data Server para JDBC e SQLJ ao caminho de construção do projeto ao clicar com o botão direito no projeto e selecionar pureQuery > Add pureQuery support....
O exemplo de aplicativo usa as seguintes entidades:
- CustomerInfo com a subclasse Customer
- District
- Item
- Order
Gere o arquivo XML do pureQuery para execução da SQL estática
Use o comando HibernateGen a fim de gerar um arquivo test.pdqxml para o exemplo de aplicativo.
O arquivo em lote para o comando (HibernateGen.bat) vem com o Integration
Module.
O caminho da classe deve conter todos os arquivos JAR de que o Hibernate precisa, junto com os seguintes arquivos:
- pdq-hibernate3.3.jar
- pdq.jar
- pdqmgmt.jar e db2jcc.jar
Se você está usando o persistence.xml, a Lista 7 mostra os comandos para definir o caminho da classe para incluir os arquivos JAR obrigatórios e executar o comando HibernateGen .
Lista 7. Gerar o arquivo pdqxml usando
HibernateGen para persistence.xml> set CLASSPATH=./pdq.jar;./pdqmgmt.jar; ./db2jcc.jar;./pdq-hibernate3.3.jar; ./hibernate3.jar;./hibernate-entitymanager.jar;./hibernate-annotations.jar; ./hibernate-common-annotations.jar;./ejb3-persistence.jar;./dom4j-1.6.1.jar; ./log4j-1.2.15.jar;./javassist-3.4.GA.jar;./antlr-2.7.6.jar; ./commons-collections-3.1.jar;./slf4j-api-1.5.2.jar;./slf4j-log4j12-1.5.2.jar; ./commons-logging-1.0.4.jar;%CLASSPATH% > HibernateGen -puName test |
Se você está usando hibernate.cfg.xml, use o comando mostrado na Lista 8 para definir o caminho da classe e executar o comando HibernateGen .
Lista 8. Gere o arquivo pdqxml usando
HibernateGen para hibernate.cfg.xml> set CLASSPATH=./pdq.jar;./pdqmgmt.jar; ./db2jcc.jar;./pdq-hibernate3.3.jar; ./hibernate3.jar;./hibernate-entitymanager.jar;./hibernate-annotations.jar; ./hibernate-common-annotations.jar;./ejb3-persistence.jar;./dom4j-1.6.1.jar; ./log4j-1.2.15.jar;./javassist-3.4.GA.jar;./antlr-2.7.6.jar; ./commons-collections-3.1.jar;./slf4j-api-1.5.2.jar;./slf4j-log4j12-1.5.2.jar; ./commons-logging-1.0.4.jar;%CLASSPATH% > HibernateGen |
Após a conclusão do comando HibernateGen , certifique-se de que ele tenha criado um arquivo com o nome test.pdqxml no diretório src.
Nota: HibernateGen gera a SQL com o JDBC padrão para resultsetHoldability.
Entretanto, o WebSphere Application Server usa um padrão diferente para o resultsetHoldability.
Se você está implementando o aplicativo de Hibernate no WebSphere Application Server, verifique o resultsetHoldability da origem de dados do WebSphere Application Server e especifique-o no comando HibernateGen , como mostra a Lista 9.
Lista 9. HibernateGen para a configuração padrão do WebSphere Application Service
> HibernateGen -resultsetHoldability 2
|
Há várias outras opções que podem ser usadas com o comando HibernateGen .
Para obter uma lista de todas as opções disponíveis, emita o comando HibernateGen com a opção -help , como mostra a Lista 10.
Listagem 10. Lista as opções do comando
HibernateGen
> HibernateGen -help
|
Configure e ligue o arquivo XML do pureQuery para a execução da SQL estática
Para executar o aplicativo estático de forma estática, primeiramente é necessário configurar e depois ligar o arquivo test.pdqxml que foi gerado.
Faça isso usando os comandos padrão do pureQuery Configure e StaticBinder
como mostra a Lista 11.
O comando StaticBinder cria os pacotes no servidor do DB2.
Certifique-se de que pdq.jar, pdqmgmt.jar e os arquivos JAR do driver correspondente de JCC estejam no caminho da classe quando você executar esses comandos.
Para obter mais informações sobre os comandos do pureQuery Configure e StaticBinder consulte a seção Recursos .
Listagem 11. Configure e ligue o arquivo XML do pureQuery
> java com.ibm.pdq.tools.Configure -rootPkgName test -pureQueryXml test.pdqxml > java com.ibm.pdq.tools.StaticBinder -url jdbc:db2://localhost:50000/demodb -username xx -password xx -pureQueryXml test.pdqxml -traceFile demo_trace.txt -traceLevel ALL |
Execute o aplicativo usando a SQL estática
A Lista 12 mostra as propriedades que são usadas no arquivo pdq.properties incluído no exemplo de aplicativo.
Listagem 12. Arquivo pdq.properties para o exemplo de aplicativo
pdq.captureMode=OFF pdq.executionMode=STATIC pdq.pureQueryXml=test.pdqxml |
Essas definições são explicadas a seguir:
captureMode=OFFindica que a captura está desativada. A captura só precisa estar ativada quando você está usando o processo de otimização de cliente que é descrito mais adiante neste artigo.executionMODE=STATICindica que o modo de execução estático (e não dinâmico) deve ser usado.pureQueryXml=test.pdqxmlproporciona o nome e o local do terceiro arquivo XML do pureQuery que foi criado quando você executou o comandoHibernateGen.
Para obter mais informações sobre todas as propriedades do pdq, consulte a seção Recursos .
No arquivo pdq.properties real incluído no exemplo de aplicativo, todas as propriedades estão com as linhas comentadas (cada linha começa com #).
Antes de continuar, edite o arquivo, exclua os #
caracteres para remover os comentários das três propriedades e salve o arquivo.
Quando você terminar, o arquivo deve estar parecido com a Lista 12.
Se você está usando persistence.xml, agora pode executar o exemplo de aplicativo ao executar MainClient.java. Para executar MainClient.java no Optim Development Studio, clique com o botão direito no arquivo e selecione Run As > Java Application. As instruções SQL do aplicativo são executadas de forma estática.
Se estiver usando hibernate.cfg.xml, execute o exemplo de aplicativo ao executar MainClientSessionFactory.java. Observe que hibernate.cfg.xml usa a classe de configuração fornecida pelo Integration Module, como mostra a Lista 13. Isso é necessário para resolver o problema descrito na seção Por que a alteração de Provider é obrigatória para possibilitar o uso de SQL estática com o Hibernate? .
public static void main(String[] args) {
_sFactory = new PDQAnnotationConfiguration().configure()
.buildSessionFactory();
|
Se você está implementando e executando o exemplo de aplicativo no WebSphere Application Server, consulte o link na seção Recursos a respeito da otimização de cliente do pureQuery em ambientes de aplicativos Web.
Habilitando os lotes heterogêneos do pureQuery para aplicativos do Hibernate
Defina as propriedades em persistence.xml
Para habilitar lotes heterogêneos de pureQuery com aplicativos de Hibernate 3.2 usando o IBM Integration Module, é necessário certificar-se de que as seguintes propriedades estejam especificadas no arquivo persistence.xml:
hibernate.jdbc.factory_classdeve ser definida comocom.ibm.pdq.hibernate3.batcher.PDQBatcherFactoryhibernate.ejb.event.flushdeve ser definida comocom.ibm.pdq.hibernate3.ejb3.listener.PDQEJB3FlushEventListener
O exemplo de aplicativo inclui essas propriedades em uma seção de comentários de persistence.xml. Portanto, no exemplo de aplicativo, é possível simplesmente editar o arquivo persistence.xml file, remover os comentários das propriedades e salvar. Com os comentários removidos, esta seção do arquivo ficará parecida com a Lista 14.
Listagem 14. Propriedades obrigatórias em persistence.xml para habilitar os lotes de pureQuery
<property name="hibernate.jdbc.factory_class" value = "com.ibm.pdq.hibernate3.batcher.PDQBatcherFactory"/> <property name="hibernate.ejb.event.flush" value = "com.ibm.pdq.hibernate3.ejb3.listener.PDQEJB3FlushEventListener"/> <property name="hibernate.connection.provider_class" value= "org.hibernate.connection.C3P0ConnectionProvider"/> |
Configure o armazenamento das instruções em cache
Para ter um bom desempenho, é importante que o armazenamento em cache das instruções esteja ativado e configurado com um tamanho razoável.
Os aplicativos de Hibernate podem usar o conjunto de conexões c3p0 para habilitar o armazenamento das instruções em cache em aplicativos de J2SE.
Para habilitar o armazenamento das instruções em cache em c3P0, defina hibernate.connection.provider_class como
org.hibernate.connection.C3P0ConnectionProvider em persistence.xml, como foi mostrado acima, na Lista 14.
Nos aplicativos de J2EE, é possível definir o armazenamento das instruções em cache no servidor de aplicativos.
O arquivo c3p0.properties especifica o tamanho do cache de instruções, como mostra a Lista 15.
Listagem 15. Especificação do tamanho do arquivo c3p0
c3p0.maxStatementsPerConnection = 200 |
O tamanho especificado para o cache de instruções deve ser relativamente grande. Normalmente, fica na faixa de 100 a 200. Em um ambiente de J2SE, se o cache de instruções for pequeno demais ou o tamanho do lote for grande demais, é possível que você receba exceções de SQL resultantes de inconsistências no cache de instruções.
Se o aplicativo de Hibernate estiver usando a API nativa do Hibernate, será necessário especificar as seguintes propriedades no arquivo hibernate.cfg.xml:
hibernate.jdbc.factory_classdeve ser definida comocom.ibm.pdq.hibernate3.batcher.PDQBatcherFactory- A classe de listener de eventos de flush deve ser definida como
com.ibm.pdq.hibernate3.listener.PDQFlushListener
O exemplo de aplicativo inclui essas propriedades em seções de comentários de hibernate.cfg.xml. Portanto, no exemplo de aplicativo, é possível simplesmente editar o arquivo hibernate.cfg.xml, remover os comentários das propriedades e salvar. Com os comentários removidos, as seções do arquivo ficarão parecidas com a Lista 16.
Listagem 16. Propriedades obrigatórias em hibernate.cfg.xml para habilitar os lotes de pureQuery
<property name="hibernate.jdbc.factory_class">
com.ibm.compdq.hibernate3.PDQBatcherFactory</property>
<event type="flush">
<listener class="com.ibm.pdq.hibernate3.listener.PDQFlushListener"/>
</event>
|
Execute o aplicativo com lotes heterogêneos
A Lista 17 mostra o arquivo persistence.xml configurado para executar o exemplo de aplicativo com a SQL estática de pureQuery e os lotes heterogêneos habilitados. Define as entidades, propriedades de conexão com o banco de dados e outras propriedades de configuração obrigatórias.
A propriedade batch_size controla o tamanho do lote de JDBC.
Também é usada pelo Integration Module para controlar o tamanho de um lote de pureQuery.
O tamanho recomendado para os lotes fica na faixa de 50 a 100.
A maioria dos benefícios dos lotes é observada na faixa de 1 a 25.
Se o lote for grande demais, é possível que você receba uma exceção de SQL com o código SQL -805.
Isso significa que o servidor de banco de dados ficou sem cursores dinâmicos.
Listagem 17. persistence.xml para o exemplo de aplicativo de Hibernate
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<provider>com.ibm.pdq.hibernate3.PDQHibernatePersistence</provider>
<!-- <provider>org.hibernate.ejb.HibernatePersistence</provider> -->
<class>demo.CustomerInfo</class>
<class>demo.Customer</class>
<class>demo.District</class>
<class>demo.Item</class>
<class>demo.Order</class>
<properties>
<property name="hibernate.connection.driver_class"
value="com.ibm.db2.jcc.DB2Driver"/>
<property name="hibernate.connection.url"
value="jdbc:db2:demodb"/>
<property name="hibernate.connection.username"
value="xx"/>
<property name="hibernate.connection.password"
value="xx"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect"/>
<property name="hibernate.hbm2ddl.auto"
value="update"/>
<property name="hibernate.jdbc.batch_size"
value = "100"/>
<property name="hibernate.jdbc.factory_class" value =
"com.ibm.pdq.hibernate3.batcher.PDQBatcherFactory"/>
<property name="hibernate.ejb.event.flush" value =
"com.ibm.pdq.hibernate3.ejb3.listener.PDQEJB3FlushEventListener"/>
<property name="hibernate.connection.provider_class" value=
"org.hibernate.connection.C3P0ConnectionProvider"/>
</properties>
</persistence-unit>
|
Nota: Se você está usando o Informix Dynamic Server, é necessário definir a propriedade hibernate.dialect em persistence.xml como InformixDialect da seguinte forma:
<property name = “hibernate.dialect” value = “org.hibernate.dialect.InformixDialect”/>
Agora é possível executar o exemplo de aplicativo ao executar MainClient.java. O processador de lotes personalizado do pureQuery garante a ocorrência de lotes heterogêneos.
Se está usando hibernate.cfg.xml, execute o exemplo de aplicativo ao executar a classe
MainClientSessionFactory.java , que usa a API SessionFactory.
Também se deve incluir o arquivo c3p0.properties no caminho do aplicativo com a propriedade
c3p0.maxStatementsPerConnection especificada.
Comparando o desempenho de tempo decorrido do exemplo de aplicativo
Esta seção descreve como determinar se o desempenho do exemplo de aplicativo melhora ao executá-lo com os lotes heterogêneos do pureQuery.
Para determinar se os lotes heterogêneos do pureQuery fornecem um benefício referente ao tempo decorrido ao executar o exemplo de aplicativo, é necessário executá-lo com os lotes heterogêneos e sem eles.
Um método de obter o tempo decorrido é executar o aplicativo usando MainClient.java ou
MainClientSessionFactory.java.
Cada uma dessas alternativas mostra o tempo decorrido total que é necessário para a execução do programa.
Outro método é ativar o rastreamento do processador de lotes. Isso permite ver como o Integration Module efetivamente está criando os lotes heterogêneos, ao mostrar quando o lote iniciou, quando as instruções são adicionadas ao lote e quando o lote termina. O exemplo de aplicativo inclui um arquivo chamado log4j.properties que pode ser usado para ativar o rastreamento do processador de lotes. Depois que o lote termina, o diretório atual contém um arquivo chamado demo.log que contém mensagens semelhantes às mostradas na Lista 18.
Listagem 18. Mensagem de rastreio em demo.log
TRACE main com.ibm.pdq.hibernate3.batcher.PDQBatcher - PureQuery batch started
Added to the batch: insert into District (d_city, d_name, d_next_o_id,
d_state, d_street_1, d_street_2, d_tax, d_ytd, d_zip, version, d_id)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Added to the batch: insert into Customer (city, fname, lname, state,
street, version, zipcode, c_balance, c_credit, c_credit_lim, c_data,
c_delivery_cnt, c_discount, c_payment_cnt, c_since, c_ytd_payment,
district_d_id, c_d_id, c_id)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Added to the batch: insert into Item (i_data, i_name, i_price, version, i_id)
values (?, ?, ?, ?, ?)
Added to the batch: insert into Order (district_d_id, itime, o_all_local, o_c_id,
o_carrier_id, o_entry_d, o_ol_cnt, version, o_d_id, o_id)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Added to the batch: update District set d_city=?, d_name=?, d_next_o_id=?, d_state=?,
d_street_1=?, d_street_2=?, d_tax=?, d_ytd=?, d_zip=?, version=?
where d_id=? and version=?
Added to the batch: update Customer set city=?, fname=?, lname=?, state=?, street=?,
version=?, zipcode=?, c_balance=?, c_credit=?, c_credit_lim=?, c_data=?,
c_delivery_cnt=?, c_discount=?, c_payment_cnt=?, c_since=?, c_ytd_payment=?,
district_d_id=? where c_d_id=? and c_id=? and version=?
Added to the batch: update Item set i_data=?, i_name=?, i_price=?, version=?
where i_id=? and version=?
TRACE main com.ibm.pdq.hibernate3.batcher.PDQBatcher - About to execute the batch
TRACE main com.ibm.pdq.hibernate3.batcher.PDQBatcher - Batch Executed.
Executed batch size=7
TRACE main com.ibm.pdq.hibernate3.batcher.PDQBatcher - Number of batches
executed in the session = 1
|
Os autores deste artigo testaram o exemplo de aplicativo com o tamanho do lote configurado como 100, em relação ao DB2 em uma máquina local e em uma máquina remota. Esse teste teve os seguintes resultados no DB2 para Linux, UNIX e Windows:
- Com o DB2 e o exemplo de aplicativo executando em uma máquina local, o pureQuery melhorou o desempenho de tempo decorrido em relação ao JDBC em mais de 40%, dependendo do número de objetos por transação. A Figura 7, abaixo, descreve esse fato. São criadas sete instruções SQL por objeto (por sua vez, são criados7 objetos de entidade diferentes por objeto).
- Com o DB2 executando em uma máquina remota e o exemplo de aplicativo executando em uma máquina local, as melhorias no desempenho de tempo decorrido variaram entre 12% e mais de 50%, dependendo do número de objetos por transação. A Figura 8, abaixo, descreve esse fato. São criadas sete instruções SQL por objeto (por sua vez, são criados 7 objetos de entidade diferentes por objeto).
Na Figura 7, o eixo X representa o número de objetos por transação. O eixo Y representa o tempo decorrido necessário para realizar a transação, em milissegundos. Observe que o gráfico indica que o tempo decorrido referente aos lotes do JDBC é maior que o tempo decorrido referente ao pureQuery.
Figura 7. JDBC X pureQuery com o servidor de banco de dados local
Na Figura 8, o eixo X representa o número de objetos por transação. O eixo Y representa o tempo decorrido necessário para realizar a transação, em milissegundos. Observe que o gráfico indica que o tempo decorrido referente aos lotes do JDBC é maior que o tempo decorrido referente ao pureQuery. Observe também que, nesse caso, conforme o número de objetos por transação aumenta, a variação do tempo decorrido entre o pureQuery e o JDBC aumenta.
Figura 8. JDBC X pureQuery com o servidor de banco de dados remoto
Usando SQL estática e lotes heterogêneos juntos
Os recursos de SQL estática e de lotes heterogêneos são ortogonais. Isso significa que um aplicativo de Hibernate pode usar SQL estática e lotes heterogêneos juntos, ao mesmo tempo, ou usar cada recurso de forma independente. Não há sobreposição de etapas na configuração de cada recurso. Para configurar a SQL estática, siga as etapas listadas em Habilitando a SQL estática do pureQuery para aplicativos de Hibernate. Para configurar os lotes heterogêneos, siga as etapas listadas em Habilitando os lotes heterogêneos do pureQuery para aplicativos do Hibernate. Para configurar ambos, basta seguir as etapas das duas seções; a ordem não importa.
Usando a captura incremental para reunir consultas de Criteria
Se o aplicativo do Hibernate usa consultas de Criteria, é possível usar a captura incremental para obter a SQL das consultas de Criteria e convertê-la para SQL estática. Para fazer isso, altere pdq.properties como mostra a Lista 19. (Existe o planejamento de futuras versões de HibernateGen.bat para suportar a geração da SQL para as consultas de Criteria.)
Listagem 19. pdq.properties para captura incremental
pdq.captureMode=ON pdq.executionMode=STATIC pdq.pureQueryXml=test.pdqxml pdq.OutputPureQueryXml=incremental_capture.pdqxml |
Quando você executa o aplicativo, ele cria um arquivo novo com o nome incremental_capture.pdqxml, que contém as SQLs que não estão presentes no arquivo pdqxml criado pelo comando HibernateGen .
É possível usar o utilitário Merge do pureQuery para mesclar os dois arquivos. Dessa forma, você obtém um único pdqxml consolidado que contém as SQLs dos dois arquivos.
A Lista 20 mostra um exemplo de execução do utilitário Merge.
Listagem 20. Executando o utilitário Merge do pureQuery
> java com.ibm.pdq.tools.Merge -outputPureQueryXml test_Merged.pdqxml -baseFile test.pdqxml -inputPureQueryXml incremental_capture.pdqxml |
Para obter mais informações sobre o utilitário Merge do pureQuery, consulte a seção Recursos .
Após a execução do exemplo do utilitário Merge mostrado na Lista 20, o arquivo test_Merged.pdqxml está pronto para a ligação. Primeiro, execute o StaticBinder em test_Merged.pdqxml, conforme o explicado na Lista 11.. Em seguida, altere pdq.properties como se mostra abaixo, na Lista 21.
Listagem 21. pdq.properties para execução de SQL estática depois da captura incremental
pdq.captureMode=OFF pdq.executionMode=STATIC pdq.pureQueryXml=test_Merged.pdqxml |
Execute o aplicativo novamente. Agora a SQL que vem das consultas de Criteria também executará de forma estática.
Este artigo é o primeiro de uma série com duas partes. Descreveu como usar o IBM Integration Module para pureQuery e Hibernate com aplicativos de Hibernate (aplicativos de Hibernate JPA e aplicativos nativos de Hibernate). Também forneceu uma breve visão geral de como usar a captura incremental para otimização de clientes do pureQuery e medições informais de desempenho em termos de tempo decorrido. A Parte 2 da série focará os aplicativos de iBATIS.
O IBM Integration Module para pureQuery e Hibernate proporciona ganhos significativos de desempenho no DB2 ao usar SQL estática. Também oferece benefícios significativos em relação ao tempo decorrido em servidores de DB2 e Informix quando são usados lotes heterogêneos com aplicativos adequados. Essas melhorias de desempenho se aplicam a ambientes J2EE e J2SE.
Os autores agradecem a Asim Singh e Ambrish Bhargava pela revisão do artigo e pelo excelente feedback.
| Descrição | Nome | Tamanho | Método de download |
|---|---|---|---|
| Sample Hibernate application for this article | DemoHibApp.zip | 27KB | HTTP |
Informações sobre métodos de download
Aprender
- Uma leitura imperdível sobre o processo de otimização de cliente.
"Tutorial:
Otimize os aplicativos de JDBC já existentes usando o pureQuery"
-
"Integrating JPA and pureQuery: Leveraging DB2 static execution for the Java Persistence API"
-
"What’s
new and cool in IBM Optim Development Studio 2.2" (developerWorks, junho de 2009)
descreve o novo suporte a Oracle e outros recursos do pureQuery que ajudam os desenvolvedores e DBAs a trabalhar melhor em conjunto.
- Visite a
página da plataforma pureQuery para ter uma visão geral da plataforma pureQuery, inclusive do valor que ela proporciona, os produtos que a acompanham e as FAQ.
-
"Database Programming for Java"
(IBM Database Magazine, maio de 2008) explica os benefícios da SQL estática e como explorar esses benefícios usando Java.
-
"Hibernate: Externalize HQL
Queries" (Javalobby, agosto de 2005) descreve como usar consultas nomeadas para externalizar consultas de HQL.
-
Mais informações sobre as propriedades do pureQuery , Configure , Static Binder e o utilitário Merge.
-
Página da família Optim no developerWorks: aprenda mais sobre as soluções Optim.
Encontre documentação técnica, artigos de instruções, educação, downloads, informações do produto e mais.
-
Fique por dentro dos eventos e webcasts técnicos do developerWorks .
-
Managing pureQuery client optimization in Web application environments.
(developerWorks, fevereiro de 2010): aprenda a otimizar aplicativos em um único nó de servidor de aplicativos.
Obter produtos e tecnologias
-
Faça o download do
IBM Integration Module para pureQuery e Hibernate.
- Faça o download e teste o
IBM Optim Development Studio e pureQuery Runtime em uma avaliação grátis de 30 dias.
- Faça o download do
Driver do IBM Data Server para JDBC e SQLJ (Driver de JCC).
Discutir
- Participar do fórum de discussão.
- Confira o
blog dos especialistas em Gerenciamento de Dados Integrados e participe do
espaço da comunidade de Gerenciamento de Dados Integrados,
que tem uma lista abrangente de recursos e downloads.

Sandhya Turaga é engenheira de software e faz parte da equipe de desenvolvimento de consulta de objetos no Laboratório IBM em Silicon Valley. Anteriormente, quando era estagiária na IBM, ela trabalhou na melhoria do desempenho de consultas para a linguagem de consulta de objetos do ObjectGrid. Adquiriu o título de mestre em Ciências da Computação pela San Jose State University em maio de 2008, com uma tese sobre computação em grade.

Abhigyan Agrawal é engenheiro de software e faz parte da equipe de Open Source nos Laboratórios de Software da IBM Índia. Atualmente, está realizando um trabalho para fornecer suporte à SQL estática de DB2 para Hibernate. Anteriormente, realizou um trabalho para fornecer suporte à SQL estática de DB2 em iBATIS e desenvolveu os drivers do IBM Python. Adquiriu o título de Mestre em Engenharia em Tecnologia da Informação pelo IIIT, em Bangalore.

Kathy Zeidenstein trabalha na IBM há muitos anos. Vem atuando em desenvolvimento de informações, gerenciamento de produtos e marketing de produtos. Atualmente, é a gerente responsável pelo desenvolvimento de informações para soluções Optim voltadas ao desenvolvimento, administração e design de banco de dados. Anteriormente, trabalhou na equipe de habilitação técnica de soluções de IBM Optim e foi responsável pelo desenvolvimento de comunidade e comunicações.

Mario Briggs é líder das ofertas de Open Source para IBM DB2 e IBM Informix, incluindo PHP, Ruby/Rails, Python/Django/SqlAlchemy, Perl e estruturas de acesso a dados Java. Mario tem aproximadamente 11 anos de experiência em desenvolvimento de software e passou vários desses anos nas áreas de acesso a dados, mecanismos relacionais e desempenho de bancos de dados de aplicativos.