我正在尝试使用标准JPA方法在Spring应用程序中实现分页。这是一个非常简单的例子:
TypedQuery<Department> depsQuery = em.createQuery("select d from Department d", Department.class);
depsQuery.setFirstResult(20);
depsQuery.setMaxResults(10);
depsQuery.getResultList();
此查询应在Informix中生成类似select skip 20 first 10
的内容。但是,它产生了这个:
select first 30 department0_.id as ... from DEPARTMENT department0_
我在<driver-class>com.informix.jdbc.IfxDriver</driver-class>
的JBoss standalone.xml
和<property name="hibernate.dialect" value="org.hibernate.dialect.InformixDialect" />
文件中persistence.xml
。如何让Hibernate / JDBC生成正确的查询?
答案 0 :(得分:3)
“org.hibernate.dialect.InformixDialect”不支持限制。这是该课程的片段:
public boolean supportsLimitOffset() {
return false;
}
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuffer( querySelect.length() + 8 )
.append( querySelect )
.insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
.toString();
}
您可以扩展此类以创建自定义方言。然后覆盖上述两种方法。
public boolean supportsLimitOffset() {
return true;
}
public String getLimitString(String querySelect, int offset, int limit) {
return new StringBuffer( querySelect.length() + 8 )
.append( querySelect )
.insert( querySelect.toLowerCase().indexOf( "select" ) + 6," skip " + offset + " first " + limit).toString();
}
答案 1 :(得分:0)
我遇到了同样的问题,上面的答案对我没有帮助。 仅覆盖getLimitString方法无效。 我也必须覆盖LimitHandler并打开一些boolean-Flags。
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.engine.spi.RowSelection;
public class TestDialect extends org.hibernate.dialect.InformixDialect {
private static final LimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
@Override
public String processSql(String sql, RowSelection selection) {
return getMyLimitString(sql, selection.getFirstRow(), selection.getMaxRows());
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean bindLimitParametersFirst() {
return true; // must do, otherwise there will be an exception cause of preparedStatments
}
};
//
////
//
public TestDialect() {
super();
}
@Override
public LimitHandler getLimitHandler() {
return LIMIT_HANDLER;
}
@Override
public String getLimitString(String querySelect, int offset, int limit) {
return getMyLimitString(querySelect, offset, limit);
}
public static String getMyLimitString(String querySelect, int offset, int limit) {
/* SQL Syntax:
* SELECT FIRST <limit> ...
* SELECT SKIP <offset> FIRST <limit> ...
*/
System.out.println("TestDialect.getMyLimitString()");
if (offset < 0 || limit < 0) {
throw new IllegalArgumentException("Cannot perform limit query with negative limit and/or offset value(s)");
}
StringBuffer limitQuery = new StringBuffer(querySelect.length() + 10);
limitQuery.append(querySelect);
int indexOfEndOfSelect = querySelect.toLowerCase().indexOf("select") + 6;
if (offset == 0) {
limitQuery.insert(indexOfEndOfSelect, " first ?" );
} else {
limitQuery.insert(indexOfEndOfSelect, " skip ?" + " first ?" );
}
return limitQuery.toString();
}
@Override
public boolean supportsLimit() {
return true;
}
}