gpt4 book ai didi

java - hibernate 分页导致选择和更新调用

转载 作者:行者123 更新时间:2023-11-29 00:53:53 25 4
gpt4 key购买 nike

我正在尝试在 hibernate 中实现分页,但我发现 hibernate 有一些奇怪的行为。我已经尝试了两个结果相同的查询

List<SomeData> dataList = (List<SomeData>) session.getCurrentSession()
.createQuery("from SomeData ad where ad.bar = :bar order by ad.id.name")
.setString("bar", foo)
.setFirstResult(i*PAGE_SIZE)
.setMaxResults(PAGE_SIZE)
.setFetchSize(PAGE_SIZE) // page_size is 1000 in my case
.list();

List<SomeData> datalist= (List<SomeData>) session.getCurrentSession()
.createCriteria(SomeData.class)
.addOrder(Order.asc("id.name"))
.add(Expression.eq("bar", foo))
.setFirstResult(i*PAGE_SIZE)
.setMaxResults(PAGE_SIZE)
.list();

我将其置于 for 循环中,每次运行此查询时,运行时间都会增加。第一个调用在 100 毫秒内返回,第二个调用在 150 毫秒内返回,第五个调用需要 2 秒,依此类推。

查看服务器 (MySql 5.1.36) 日志,我看到选择查询确实使用 LIMIT 子句正确生成,但对于返回的每条记录,hibernate 出于某种原因也会发出更新查询。在第一个结果之后,它更新 1000 条记录,在第二个结果之后,它更新 2000 条记录,依此类推。因此,对于 1000 的页面大小和 5 次循环迭代,数据库会遇到 15,000 个查询(5K + 4K + 3K + 2K + 1K),为什么会这样?

我尝试创建一个本地 SQL 查询,它按预期工作。查询是

List asins = (List) session.getCurrentSession()
.createSQLQuery("SELECT * FROM some_data where foo = :foo order by bar
LIMIT :from , :page")
.addScalar(..)
.setInteger("page", PAGE_SIZE)
.setInteger("from", (i*PAGE_SIZE))
... // set other params
.list();

我的映射类有 blob 对象的 setter/getter 作为

void setSomeBlob(Blob blob){
this.someByteArray = this.toByteArray(blob)
}

void Blob getSomeBlob(){
return Hibernate.createBlob(someByteArray)
}

最佳答案

打开绑定(bind)参数日志记录(您可以通过将“org.hibernate.type”日志级别设置为“TRACE”来实现)以查看具体更新的内容。

很可能您在加载实体后对其进行修改 - 显式或隐式(例如,从 getter 返回不同的值或在某处使用默认值)。

另一种可能性是您最近更改了您要从中选择的(一个或多个)表,并且表中的列默认值与实体中的默认值不匹配。

关于java - hibernate 分页导致选择和更新调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7072695/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com