我正在使用java / hibernate / mysql。我正在创建一个我想要保存到数据库的对象列表。有些项目是新的,有些项目已经在数据库中(我不知道哪些项目)。因此我使用session.SaveOrUpdate方法,必要时可以正常插入并在必要时进行更新。
问题是我每次调用saveOrUpdate(myObject)时都会看到有一个select调用来检查这条记录是否已经存在,所以如果我遍历N个对象我有N - 选择查询。有什么方法可以将这些选择一起批处理吗?
此行为是否会对性能产生重大影响?
由于
我得到的日志是:
Hibernate: select price0_.product_id as product1_3_0_, price0_.store_id as
store2_3_0_, price0_.date_updated as date3_3_0_, price0_.price as price3_0_,
price0_.quality as quality3_0_, price0_.update_source as update6_3_0_
from realworld.price price0_ where price0_.product_id=? and price0_.store_id=?
Hibernate: select price0_.product_id as product1_3_0_, price0_.store_id as
store2_3_0_, price0_.date_updated as date3_3_0_, price0_.price as price3_0_,
price0_.quality as quality3_0_, price0_.update_source as update6_3_0_
from realworld.price price0_ where price0_.product_id=? and price0_.store_id=?
Hibernate: insert into realworld.price
(date_updated, price, quality, update_source, product_id, store_id)
values (?, ?, ?, ?, ?, ?)
Hibernate: insert into realworld.price
(date_updated, price, quality, update_source, product_id, store_id)
values (?, ?, ?, ?, ?, ?)
生成此代码的代码是:
for (Price price : prices){
HibernateCurrentSession.currentSession().merge(price);
i++;
if ( i % batchsize == 0 ) {
//flush a batch of inserts and release memory:
HibernateCurrentSession.currentSession().flush();
HibernateCurrentSession.currentSession().clear();
}
}
答案 0 :(得分:1)
嗯,首先,那些选择和什么都没有在同一个事务中执行所以它们应该工作得非常快。您得到它们的原因可能是,对于现有条目,Hibernate可能希望首先检查版本字段(通过将其当前值与数据库中已有的值进行比较),这将在更新之前发出选择。有关saveOrUpdate行为的更多详细信息,请参见here
我认为您无法在此上下文中控制或批量选择这些选项。你能做些什么来提高效率是这样的:
Session.merge(obj)
答案 1 :(得分:0)
您可以发布我们的地图文件吗?这可能是因为属性“select-before-update”为真。默认情况下为false。如果这确实是假的并且您正在使用乐观锁定,则在更新之前不会选择。检查this,它解释了Hibernate中的乐观锁定以及更新的发生方式。