Criteria setMaxResults(int maxResults) >Set a limit upon the number of objects to be retrieved.
假设我有以下标准:
Criteria criteria = createCriteria(); // creates criteria for MY_TABLE entity criteria.list().length; // let's say there's a million records in this table
添加criteria.setMaxResults(1)会只返回一行吗?或者,它仍将返回100万行,但选择其中一行?
在针对我的Oracle DB运行类似于上面的代码示例的查询时,我看到了…… ROWNUM< 2正在生成sql. 但是,当我查看ROWNUM FAQ时,我不明白在检索记录之前是否应用ROWNUM,或之后.我希望“之前”是有效的,而“之后”则不适用于大的结果集.
ROWNUM is evaluated AFTER records are selected from the database and
BEFORE the execution of ORDER BY clause.
解决方法
Will adding criteria.setMaxResults(1) return only a single row? Or,
will it still return 1 million rows,but pick one of them?
是的,它只返回一行,hibernate使用db特定功能来限制结果.
Hibernate将不会拾取100万行,但db会选择第一行(此语句与hibernate而不是ROWNUM生成的查询有关).
假设您有一个名为user的表,其中有8行.
+----+-----------+-------+ | id | name | score | +----+-----------+-------+ | 1 | Xyz | 500 | | 2 | Name3 | 200 | | 3 | Name2 | 300 | | 4 | Name4 | 100 | | 5 | SomeName | 600 | | 6 | BSomeName | 150 | | 7 | Asomename | 80 | | 8 | Csomename | 700 | +----+-----------+-------+
现在,您运行以下条件.
criteria.add(Restriction.le("score",500)); criteria.addOrder(Order.asc("name")); criteria.setMaxResults(2);
select * from(select * from user where score <= 500 order by name) where ROWNUM < 3;
DB将按以下顺序执行它.
>找到得分小于或等于500的所有行.这里将找到6行.
>按名称按升序排序所有行.
>为每行分配ROWNUM.
>找到ROWNUM小于3的所有行并返回它们.
结果将是.
+----+-----------+-------+ | id | name | score | +----+-----------+-------+ | 7 | ASomeName | 80 | | 6 | Bsomename | 150 | +----+-----------+-------+
无论有多少记录,DB都会执行上述步骤,所以当你有顺序并且有很多行满足条件时,查询会非常慢.
I didn’t understand if ROWNUM will be applied before retrieving
records,or after. I would expect “before” to be efficient,whereas
“after” would not be for a large result set.
ROWNUMS是给满足所有给定条件的行的索引. DB将继续检查每一行是否应用WHERE子句中提供的所有条件,如果everythig没有问题,则为该行分配一个数字,然后转到下一行.正如文档所说,评估ROWNUM后,从数据库中选择记录意味着满足所有条件.
BEFORE the execution of ORDER BY clause.
ROWNUM与其他数据库(MysqL,Postgrage等)中的LIMIT不同.即LIMIT查找所有行,对它们进行排序,然后返回有限的结果.
而ROWNUM一旦满足所有条件就会被分配给行.这就是hibernate生成内部查询以获得一致排序结果的原因.
如果执行以下查询,则使用上表中给出的相同数据.
select * from user where score <= 500 where row_num < 3 order by name;
您将获得以下结果.
+----+-----------+-------+ | id | name | score | +----+-----------+-------+ | 3 | Name2 | 300 | | 2 | Name3 | 200 | +----+-----------+-------+
这是因为DB开始寻找满足条件的行(得分<= 500),给它们每个ROWNUM索引,直到ROWNUM< 3,然后按名称排序行.
一旦根据查询的其余部分将行标识为结果集的一部分,Oracle将应用rownum谓词