首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >informix数据库分页

informix数据库分页
EN

Stack Overflow用户
提问于 2019-12-11 14:38:27
回答 1查看 930关注 0票数 1

我试图为Informix进行分页,但是Hibernate方言有一些限制,因为它不会生成有限的查询。当我检查Informix时,手册告诉我以下答案:

代码语言:javascript
复制
"The Projection clause cannot include the SKIP, FIRST, or LIMIT keywords in these contexts:

when the SELECT statement is part of a view definition
in a subquery, except in the FROM clause of the outer query
in a cross-server distributed query in which a participating database server does not support the SKIP, FIRST, or LIMIT keywords."

我正在尝试为极限类编写自己的实现,并在加载Hibernate方言时加载它。但是每次我启动应用程序时,它都会选择默认的方言,而不是我的。

hibernate中有一个问题-- https://hibernate.atlassian.net/browse/HHH-5414

这个补丁不适用于我的本地人。但是,我担心DB本身不支持,如果我尝试手动完成这个操作,效率会有多大,因为这将是一个基于偏移的分页,我认为这会影响性能,可能解决不了问题。

考虑到这些对informix分页支持的场景,我想知道最好的方法是什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-07 13:20:09

是的,现在Hibernate已经解决了这个问题(至少在5.3.10的mostly redhat-00001中,我们主要使用的是jBoss-EAP7服务器),您只需要添加您的

代码语言:javascript
复制
<property name="hibernate.dialect" value="org.hibernate.dialect.Informix10Dialect" />

对于您的persistence.xml来说,它工作得很好。我指的是代码行中的

代码语言:javascript
复制
if (pageSize > 0) {
    int firstResult = pageNo * pageSize - pageSize;
    query.setFirstResult(firstResult);
    query.setMaxResults(pageSize);
}

其中查询是一个javax.persistence.Query。

一个合理的期望触发这样的查询将是表单上的SQL‘本机’输出。

代码语言:javascript
复制
select skip <firstResult> limit <pageSize> [rest of the select statement]

发送到informix。然而,Hibernate直到Hibernate 5才修复这个问题。

也许它不是很漂亮,但是在古老的JBOSSes或其他可怕的旧平台中,引入/要求古老的hibernate版本,您能做的是自己修复代码。不久前,我们还经常攻击hibernate-core。

代码语言:javascript
复制
hibernate-core-4.x.x.Final

黑了

代码语言:javascript
复制
hibernate-core-4.x.x.Final-pagination 

它只是在取代课堂

代码语言:javascript
复制
org.hibernate.dialect.InformixDialect
org.hibernate.dialect.pagination.NoopLimitHandler
org.hibernate.dialect.pagination.FirstLimitHandler

因此,这些首先支持limitOffSet的

代码语言:javascript
复制
@Override
public boolean supportsLimitOffset() {
    return true;
}

然后我们用一些简单的方式来实现这些东西,比如

代码语言:javascript
复制
public final class InformixDialect extends Dialect {
..
private static final String SKIP = " SKIP ";
private static final String FIRST = " FIRST ";
private static final String SELECT = "select";
private static final int SELECT_LEN = SELECT.length();
..  
@Override        
public String getLimitString(String querySelect, int offset, int limit) {
    return new StringBuilder(querySelect.length() + 8)
            .append(querySelect)
            .insert(querySelect.toLowerCase().indexOf(SELECT) + SELECT_LEN, new StringBuilder(SKIP).append(offset).append(FIRST).append(limit).toString()).toString();
}
..

和(NoopLimitHandler完全相同)

代码语言:javascript
复制
public final class FirstLimitHandler extends AbstractLimitHandler {
..
private static final String SKIP = " SKIP ";
private static final String FIRST = " FIRST ";
private static final String EMPTY = "";
private static final String SELECT = "select";
private static final int SELECT_LEN = SELECT.length();
..
@Override
public int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index) {
    return 0;
}

@Override
public int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index) {
    return 0;
}
..
@Override
public String processSql(String sql, RowSelection selection) {
    if (selection == null || selection.getFirstRow() == null) {
        return sql;
    }
    boolean hasOffset = LimitHelper.hasFirstRow(selection);
    int maxOrLimit = this.getMaxOrLimit(selection);
    String sqlOffset = hasOffset? SKIP + selection.getFirstRow(): EMPTY;
    String sqlLimit = maxOrLimit > 0 ? FIRST + this.getMaxOrLimit(selection): EMPTY;
    String sqlOffsetLimit = sqlOffset + sqlLimit;
    return new StringBuilder(sql.length() + 10).append(sql).insert(sql.toLowerCase(Locale.ROOT).indexOf(SELECT) + SELECT_LEN, sqlOffsetLimit).toString();
}
..

针头说,如果你可以使用Hibernate 5,这当然是更好的替代

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59288179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档