Hibernate更新部分字段浅谈

update语句是在Hibernate的Configuration的时候生成的,不能动态改变。为什么update的时候所有的属性都一起update,而不是只更新改变字段,其实这是一个比较值得探讨的问题。

如果想要做到只更新改变了的字段,必须做到两点:
1、对PO的每个属性设置version进行状态跟踪
2、update语句是动态生成的,在实际向数据库更新的时候,依次检查每个属性的version,决定哪些属性需要更新,动态构造update语句。

单单要做到上述第一点,就势必要给PO的操作带来沉重的负担,每次属性的存取都要判断version,严重影响PO的性能。会带来整个Hibernate性能的降低。而要做到第二点,临时构造update语句时间消耗很客观,也会极大降低update的速度。

Hibernate的PO状态管理是当任何属性值改变的时候,version就被标记,表明PO被更新了。实现很简单而有效,效率非常高。而update语句insert,delete和某几个select语句是在Hibernate初始化过程中就构造好了,不需要用的时候临时构造。

综合评价得与失,对PO属性进行状态管理固然可以稍微降低数据库负担,但是会极大影响Hibernate的运行效率,终究得不偿失。

这里说明一点,如果一个属性的值变为空,则hibernate也认为该属性的值已经改变,直接update操作就会将空值同步到数据库中。

以上内容是执行update操作更新改变字段的数据时hibernate的处理。这里得不出我想要的结果。因为我的需求有两点不能忽略:一、我更新的字段,数据不一定改变,这些字段一定要保证数据的同步。二、我不更新的字段,即使数据有变,也不能做同步操作。

既然动态设置一个属性的值是否改变是一件比较难的事情,那就最好转换一下思路。当然hibernate也有比较折中的方法可以处理。这里就我总结的,浅谈一下。

方式一:通过HQL或者SQL来实现。这是最笨拙的方式,具体就是写HQL或者SQL语句了,我在此就不细说。

方式二:一一设置需要更新的字段。首先,重新查询一次,然后对这个刚查询出来的对象一一设置需要改变的字段的值,然后再update。这种方式实现起来也是比较让人痛苦的,跟操作JDBC没多大区别。

方式三:在页面隐藏不需要改变的值。在修改页面,隐藏那些无需操作的字段,提交的时候hibernate会自动提交这些隐藏的字段的值。这种方式对于一个多字段的表不太适用。

方式四:在方式二的基础上进行。一一设置需要更新的字段是比较痛苦的,那有没有工具可以帮助我们处理这样的操作呢。答案是肯定的。Spring是一款很优秀的框架。它内置的BeanUtils工具类可以轻松实现这些功能,而且效率极高。BeanUtils的copyProperties方法进行了重载,其中一个如下:

org.springframework.beans.BeanUtils.copyProperties(source, target, ignoreProperties)

其中第一个参数是数据源,第二个参数是目标对象,第三个参数用来过滤哪些属性不需要进行拷贝,这样在进行更新时就方便多了。

这里没有哪一种方式更好,哪一种方式不好,具体场合具体对待吧。如果需要更新的字段远远多于需要更新的字段,建议采用方式三或者方式四。如果需要更新的字段就那么几个,则可以采用方式一或方式二。

时间: 2024-08-01 09:08:02

Hibernate更新部分字段浅谈的相关文章

Hibernate更新某些字段的几种update方法

Hibernate 中如果直接使用 Session.update(Object o); 会把这个表中的所有字段更新一遍. 比如: [java] view plaincopy public class TeacherTest { @Test public void update(){ Session session =  HibernateUitl.getSessionFactory().getCurrentSession(); session.beginTransaction(); Teache

Hibernate 更新部分字段的实现

在Hibernate 中,有时我们只需要更新部分字段,此时如果使用update()方法,会将所有字段都更新,对于没有set的字段,就会设置成NULL,如果这些字段里面有非空的字段就会报错. 解决的方法可以直接写HQL语句,但是如果字段较多,并且更新的字段是不确定的时候,直接写HQL语句就显得比较麻烦. 另一种方法是在XML文件中设置dynamic-update="true",这样设置以后,只对set了的字段更新,没有set的字段就不会更新. <class name="c

浅谈Hibernate关系映射(3)

继上篇博客 一对多关联映射(单向) 上面我们介绍了多对一,我们反过来看一对多不就是多对一吗?那还用再进行不同的映射吗?有什么差别吗?一对多和多对一映射原理是一致的,存储是相同的,也就是生成的数据库的表是一样的,他们之间不同的是维护的关系不同. 他们之间不同点是维护的关系不同 *多对一维护的关系是:多指向一的关系,有了此关系,加载多的时候可以将一加载上来. *一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来. 一个班级有多个学生,通过班级可以看到学生信息. Class

浅谈Hibernate关系映射(2)

继上篇博客 一对一关系映射:一对一关联映射在实际生活中是比较常见的,如人与身份证的关系,通过人这个对象可以找到他相关的内容. 一对一单向(主键): 单向一对一主键关联,靠的是它们的主键相等,从Person中能看到IdCard,也就是把t_idCard中的主键拿过来当做t_Pseron的主键. 如图的线表示一个关联,在person中可以看见idcard.即在person中持有idCard的引用 person类的映射关系 <hibernate-mapping> <class name=&qu

浅谈Hibernate关系映射(4)

继上篇博客 多对多关联映射(单向) 多对多对象关系映射,需要加入一张新表完成基本映射. Hibernate会自动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联,多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的. 如下图所示 通过User可以查看Role的信息 User的映射文件 <hibernate-mapping> <class name="com.bjpowernode.hibernate.User"> <

hibernate update 只更新部分字段的3种方法(其实我只想说第二种)

hibernate 中如果直接使用Session.update(Object o);会把这个表中的所有字段更新一遍. 比如: public class Teacher Test { @Test public void update(){ Session session = HibernateUitl.getSessionFactory().getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher) session.

浅谈相对论【更新ing】

前言 我是通过乐乐课堂学习相对论的冰山一角的,在此感谢! 物理学可以分为两个阶段:经典物理学和近代物理学.像牛顿力学.光学.热学.电磁学,都是20世纪以前的科学家努力的成果.20世纪初,著名物理学家威廉汤姆逊甚至这样宣称: 科学的大厦已经基本完成,未来的物理学家只要做一些修修补补的工作就可以啦! 但汤姆逊也同时指出: 在物理学明朗的天空中,飘着两朵小小的乌云:一朵是黑体辐射.另一朵是迈克尔孙莫雷实验. 这两朵小小的乌云后来却下起了狂风骤雨,把经典物理学的大厦吹打得七零八落.但他们最终也孕育出了两

【架构】浅谈web网站架构演变过程

浅谈web网站架构演变过程 前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变. 该系统具备的功能: 用户模块:用户注册和管理 商品模块:商品展示和管理 交易模块:创建交易和管理 阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架如maven+spring+struct+hibernate.maven+spri

关系型数据库表结构设计规范-浅谈(转)

数据库表结构设计规范-浅谈,为啥是浅谈呢,因为主要的观点还是来自原微信公共账号的一篇文章,稍微加了一些自己的看法. 谁来进行数据库的设计? 肯定是具体的开发工程师来进行,开发同学的话,第一业务熟悉度比较高,第二结合OO和ORM的思想,能有比较好的运用关系型数据库的特性.如果是DBA同学的话,虽然对于数据库本身了解比较多,但是对于业务了解较少,很难有比较客观的设计.但是业务上线或者运行期间,需要DBA同学能够重度的加入进来,针对一些性能点和不合理的点进行优化,同事也可以在上线前,针对SQL进行re