在Hibernate 3中,是否有一种方法可以在HQL中实现与以下MySQL限制相同的功能?
select * from a_table order by a_table_column desc limit 0, 20;
如果可能的话,我不想使用setMaxResults。在旧版本的Hibernate/HQL中,这是绝对可能的,但它似乎已经消失了。
在Hibernate 3中,是否有一种方法可以在HQL中实现与以下MySQL限制相同的功能?
select * from a_table order by a_table_column desc limit 0, 20;
如果可能的话,我不想使用setMaxResults。在旧版本的Hibernate/HQL中,这是绝对可能的,但它似乎已经消失了。
当前回答
如果可以在此模式下管理一个限制
public List<ExampleModel> listExampleModel() {
return listExampleModel(null, null);
}
public List<ExampleModel> listExampleModel(Integer first, Integer count) {
Query tmp = getSession().createQuery("from ExampleModel");
if (first != null)
tmp.setFirstResult(first);
if (count != null)
tmp.setMaxResults(count);
return (List<ExampleModel>)tmp.list();
}
这是一个处理限制或列表的非常简单的代码。
其他回答
String hql = "select userName from AccountInfo order by points desc 5";
这为我工作,没有使用setmaxResults();
只在最后一个(在本例中是5)中提供最大值,而不使用关键字limit。 : P
如果您不想在Query对象上使用setMaxResults(),那么您总是可以恢复到使用普通SQL。
如果不想使用setMaxResults,也可以使用Query。滚动而不是列表,并获取您想要的行。例如,对于分页很有用。
如果可以在此模式下管理一个限制
public List<ExampleModel> listExampleModel() {
return listExampleModel(null, null);
}
public List<ExampleModel> listExampleModel(Integer first, Integer count) {
Query tmp = getSession().createQuery("from ExampleModel");
if (first != null)
tmp.setFirstResult(first);
if (count != null)
tmp.setMaxResults(count);
return (List<ExampleModel>)tmp.list();
}
这是一个处理限制或列表的非常简单的代码。
setFirstResult和setMaxResults查询方法
对于JPA和Hibernate查询,setFirstResult方法相当于OFFSET, setMaxResults方法相当于LIMIT:
List<Post> posts = entityManager.createQuery("""
select p
from Post p
order by p.createdOn
""")
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
LimitHandler抽象
Hibernate LimitHandler定义了特定于数据库的分页逻辑,如下图所示,Hibernate支持许多特定于数据库的分页选项:
现在,根据所使用的底层关系数据库系统,上面的JPQL查询将使用正确的分页语法。
MySQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?, ?
PostgreSQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
SQL Server
SELECT p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
OFFSET ? ROWS
FETCH NEXT ? ROWS ONLY
甲骨文
SELECT *
FROM (
SELECT
row_.*, rownum rownum_
FROM (
SELECT
p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
) row_
WHERE rownum <= ?
)
WHERE rownum_ > ?
使用setFirstResult和setMaxResults的优点是Hibernate可以为任何受支持的关系数据库生成特定于数据库的分页语法。
而且,您不仅限于JPQL查询。对于本地SQL查询,可以使用setFirstResult和setMaxResults方法7。
本地SQL查询
在使用本机SQL查询时,不必硬编码特定于数据库的分页。Hibernate可以将其添加到查询中。
所以,如果你在PostgreSQL上执行这个SQL查询:
List<Tuple> posts = entityManager.createNativeQuery(
SELECT
p.id AS id,
p.title AS title
from post p
ORDER BY p.created_on
""", Tuple.class)
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
Hibernate将对其进行如下转换:
SELECT p.id AS id,
p.title AS title
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
很酷,对吧?
超越基于sql的分页
当您可以索引过滤和排序条件时,分页是很好的。如果您的分页需求意味着动态筛选,那么使用倒索引解决方案(如ElasticSearch)是更好的方法。