2

我正在尝试使用标准 JPA 方法在我们的 Spring 应用程序中实现分页。这是一个非常简化的示例:

TypedQuery<Department> depsQuery = em.createQuery("select d from Department d", Department.class);
depsQuery.setFirstResult(20);
depsQuery.setMaxResults(10);
depsQuery.getResultList();

此查询应生成类似于select skip 20 first 10Informix 中的内容。但是,它会生成:

select first 30 department0_.id as ... from DEPARTMENT department0_

<driver-class>com.informix.jdbc.IfxDriver</driver-class>standalone.xmlJBoss 和文件<property name="hibernate.dialect" value="org.hibernate.dialect.InformixDialect" />中都有。persistence.xml如何让 Hibernate/JDBC 产生正确的查询?

4

2 回答 2

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();
}
于 2013-10-07T08:07:35.537 回答
0

我遇到了同样的问题,上面的答案对我没有帮助。只覆盖getLimitString 方法是没有效果的。我也必须覆盖 LimitHandler 并打开一些布尔标志。

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;
    }
}
于 2016-08-18T12:47:14.270 回答