在“旧的JDBC时代”中,我写了很多SQL代码,只对实际更改的“属性/成员”进行了非常有针对性的更新:
例如,考虑具有以下成员的对象:
public String name;
public String address;
public Date date;
如果在某些商业方法中仅更改date
,我只会为UPDATE
成员发出SQL date
。
我的问题是:
这个观察是否正确,Hibernate 不会智能地检查(在完全映射的类中),哪些成员发生了更改,然后只为特定的更改成员发布更新,但是总是会更新(在生成的SQL更新语句中)所有映射成员(类),即使它们没有被更改(如果对象由于一个成员变脏而变脏...)
< / LI>如何让Hibernate更新那些已被更改的成员?我正在寻找一种解决方案让Hibernate只更新实际更改的成员。
(我知道Hibernate在脏检查方面做了很多工作,但据我所知,这个脏检查仅与识别整个对象是否脏,而不是单个成员是脏的有关。)
答案 0 :(得分:15)
实际上,您可以在类映射中指定选项dynamic-update
和dynamic-insert
。就是这样。更多信息here。
答案 1 :(得分:5)
Hibernate 只是更新您真正想要的内容
public class Person {
private Integer id;
public String name;
public String address;
public Date date;
// getter's and setter's
}
你做的事情就像
Person person = (Person) sessionFactory.openSession().get(Person.class, personId);
person.setName("jean");
Hibernate非常聪明,只知道名称属性已被更改。虽然您可以看到您的日志如下
UPDATE PERSON (NAME, ADDRESS, DATE) VALUES (?, ?, ?);
因为Hibernate再次为每个实体缓存每个SQL(INSERT,UPDATE,SELECT)查询,它只是更新你真正想要的东西。
答案 2 :(得分:2)
您可以通过实现CustomEntityDirtinessStrategy或Interceptor等接口来优化脏检查。 请参阅http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp
上的工作示例答案 3 :(得分:0)
我认为如果你有大量的数据库负载和一个或多个索引要在完全更新(其中所有列都被更新,还有那些未更改的值)上重新创建,那么动态更新是很好的。
也许某些DBMS会识别UPDATE是否设置已存在的值以不更新包含该列的索引。但是许多人似乎太“愚蠢”地认识到这一点(或者出于性能原因不进行检查)。
对于大多数数据库客户端应用程序,创建SQL查询的客户端负载不是问题。在数据库中解释SQL应该比重新创建一个大索引花费更少的时间。
如果我错了,请纠正我!