使用Hibernate查询DB2时Query接口setFetchSize方法的正确使用方式
公司有个项目,采用DB2数据库,持久化技术为Hibernate。近期有个同事发现Hibernate生成的分页SQL语句查询速度很慢,凭经验,他在该sql语句后面加上了
fetch first 10 rows only
查询速度一下子提高上去了,因此他在Hibernate中的Query调用中增加了.setFetchSize(10)。但是发现Hibernate解析出来的sql并没有增加上面的fetch子句。
其实这个问题的原因在于Hibernate的Dialect不正确,一般的,我们会选择org.hibernate.dialect.DB2Dialect,但其实应该选择org.hibernate.dialect.DB2400Dialect,该类源代码(部分):
public String getLimitString(String sql, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuffer( sql.length() + 40 )
.append( sql )
.append( " fetch first " )
.append( limit )
.append( " rows only " )
.toString();
}
注意到,DB2400Dialect类是继承于DB2Dialect类的。
这样改后, Hibernate解析出来的sql语句就顺利地加上fetch子句了。
另记录一下搭建测试代码时碰到的一些问题:
1. DB2的JDBC驱动:我在MAC上使用DbVisualizer-8.0.9,该工具自带了DB2的一个驱动包,放置于/Applications/DbVisualizer-8.0.9.app/Contents/Resources/app/jdbc/db2/db2jcc.jar,手工install到本地Maven仓库
$mvn install:install-file -Dfile=db2jcc.jar -DgroupId=com.ibm.db2.jcc -DartifactId=db2jcc -Dversion=8 -Dpackaging=jar
2. Hibernate版本: 搭建测试代码时,首先使用的是Hibernate4,pom文件(部分):
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.2.Final</version>
<!--
<exclusions>
<exclusion>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</exclusion>
</exclusions>
-->
</dependency>
运行测试代码时报错:
DEBUG: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Could not open connection
java.sql.SQLException: No suitable driver found for jdbc:db2://(略去)
at java.sql.DriverManager.getConnection(DriverManager.java:602)
at java.sql.DriverManager.getConnection(DriverManager.java:154)
死活不知道原因,后来将Hibernate版本降至3.6.0.Final,顺利通过测试,相关pom文件
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.0.Final</version>
<!--
<exclusions>
<exclusion>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</exclusion>
</exclusions>
-->
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
<!--
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.2.145</version>
</dependency>
-->
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc</artifactId>
<version>8</version>
</dependency>
</dependencies>
唔,从这方面以及控制台输入的日志内容看Hibernate4对比Hibernate3的改动是非常大的。
至于为什么Hibernate4报错,留给未来*有时间*再研究吧。
参考链接:
What is difference between setMaxResults and setFetchSize in org.hibernate.Query?
Can not get N first results of query with DB2 dialect (neither with setMaxResults nor with setFetchSize)
页:
[1]