docs说:
Criteria setMaxResults(int maxResults)
>Set a limit upon the number of objects to be retrieved.
我们说我有以下Criteria
:
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时,我不明白在检索记录之前或之后是否会应用{strong}
在从数据库中选择记录后评估ROWNUM
在执行ORDER BY子句之前。
答案 0 :(得分:13)
添加criteria.setMaxResults(1)会只返回一行吗?要么, 它仍会返回100万行,但选择其中一行吗?
是的,它只返回一行,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);
Hibernate生成以下查询。
select * from(select * from user where score <= 500 order by name) where ROWNUM < 3;
DB将按以下顺序执行。
ROWNUM
分配给每一行。ROWNUM
小于3的所有行并返回它们。结果将是。
+----+-----------+-------+
| id | name | score |
+----+-----------+-------+
| 7 | ASomeName | 80 |
| 6 | Bsomename | 150 |
+----+-----------+-------+
无论有多少记录,DB都会执行上述步骤,所以当你有顺序并且有很多行满足条件时,查询会非常慢。
我不知道在检索之前是否会应用ROWNUM 记录,或之后。我期待&#34;之前&#34;要有效率,而 &#34;后&#34;不会是一个大的结果集。
ROWNUMS
是给满足所有给定条件的行的索引。 DB将继续检查每一行是否应用WHERE子句中提供的所有条件,如果everythig没有问题,则为该行分配一个数字,然后转到下一行。正如文件所说,ROWNUM is evaluated AFTER records are selected from the database
意味着满足所有条件。
在执行ORDER BY子句之前。
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&lt; 3,然后按名称排序行。 一旦根据查询的其余部分将行标识为结果集的一部分,Oracle将应用rownum谓词