- 浏览: 1112821 次
文章分类
- 全部博客 (379)
- S2SH (16)
- stuts2 (0)
- java语言 (81)
- JSP (17)
- <html>元素 (11)
- javaweb (4)
- web容器 (3)
- ext (23)
- javaScript (48)
- ant (1)
- liferay (1)
- sql (9)
- css (42)
- 浏览器设置 (3)
- office_world (1)
- eclipse (4)
- 其它 (28)
- 操作系统 (5)
- android (6)
- Struts2 (11)
- RegEx (3)
- mysql (5)
- BigDATA (1)
- Node.js (1)
- Algorithm (10)
- Apache Spark (1)
- 数据库 (5)
- linux (2)
- git (1)
- Adobe (3)
- java语言,WebSocket (1)
- Maven (3)
- SHELL (1)
- XML (2)
- 数学 (2)
- Python (2)
- Java_mysql (1)
- ReactJS (6)
- 养生 (4)
- Docker (1)
- Protocols (3)
- java8 (2)
- 书籍 (1)
- Gradle (2)
- AngularJS (5)
- SpringMVC (2)
- SOAP (1)
- BootstrapCSS (1)
- HTTP协议 (1)
- OAuth2 (1)
最新评论
-
Lixh1986:
Java并发编程:自己动手写一把可重入锁https://blo ...
Java之多线程之Lock与Condition -
Lixh1986:
http://win.51apps.com.cn/https: ...
temp -
ztwsl:
不错,支持很好
HttpServletRequest和ServletRequest的区别 -
guodongkai:
谢谢您能将知识精华汇编总结,让初学者们从原理中学会和提高。
javaScript之function定义 -
kangwen23:
谢谢了,顶顶
struts2中的ValueStack学习
一、情景描述
鉴于:hibernate是面向对象(实体、entity)操作,而不是某个对象的字段或属性。
鉴于:使用hibernate从数据库获取对象后,无需对数据库操作,而是直接操作获取的对象,hibernate就可以自动同步数据库。
因此:hibernate将对象分为三种状态,以便进行区分和管理:
1:瞬时/临时(Transient)
可以理解为该对象和hibernate一点关系也没有。
对该对象的操作不会和hibernate有任何联系或影响。
2:持久(Persistent)
使用hibernate对该对象进行管理,这会涉及到hibernate自动对数据库的相应的操作。
更细节的解释:
(hibernate通过对外提供session对象,和session对象的一系列方法,完成对数据的增删改查。hibernate自动对数据库的操作也是依赖于和session绑定)。
也就是说,在持久状态下,hibernate对对象的操作和seesion是分不开的。
3:脱管/游离(Detached)
这种状态是根据hibernate是否建立了session链接,以便与第2种状态进行区分。
可以理解为除了没有建立session(未连接数据库),其它的和第2种状态都一样。
hibernate已经对该对象进行绑定,并管理。只是没有建立session链接。
二、词汇定义
1:瞬时/临时(Transient) - 由new操作符创建,且尚未与Hibernate Session 关联的对象被认定为瞬时的。瞬时对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)。 如果瞬时对象在程序中没有被引用,它会被垃圾回收器销毁。
2:持久(Persistent) - 持久的实例在数据库中有对应的记录,并拥有一个持久化标识。 持久的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。 Hibernate会检测到处于持久状态的对象的任何改动,在当前操作单元执行完毕时将对象数据与数据库同步。开发者不需要手动执行UPDATE。
3:脱管/游离(Detached) - 与持久对象关联的Session被关闭后,对象就变为脱管的。 对脱管对象的引用依然有效,对象可继续被修改。脱管对象如果重新关联到某个新的Session上, 会再次转变为持久的,在脱管期间的改动将被持久化到数据库。
三、理解这三种状态的意义
便于使用hibernate提供的各种方法。意义是重大的。
比如:
merge()
session.close()对对象状态的影响
获取新的session后,对象状态,对数据库造成的影响。
四、讨论
说,这三种状态是hibernate的对象的生命周期,是不准确的。
因为每个状态都不是对象必须经过的。
但是这对象在这三种状态中可以相互转换。
就是状态。对象在hibernate中所表示的三种状态。
五、应用举例
1、关于merge方法
什么时候用?:
这个方法就是为在前台修改从后台读取的数据准备的。
【hibernate 需要设置为: hibernate update部分更新。因为直接使用merge()方法,会把数据库中有而传递过来的对象中没有的字段,会重置。这样就得在传参数时,把数据库中的字段都得写全。
具体参照:】
http://www.cnblogs.com/hyteddy/archive/2011/07/21/2113175.html
【其实,merge()方法解决了新new一个对象时,如何将其同步到数据库中去的问题。但是,需要把所有的字段写全,需要在前台页面中添加隐藏变量,这显然是不一个好方法。关于如何实现hibernate部分字段更新问题,请看这里(内容会拷贝到本文后面):】
http://www.rritw.com/a/JAVAbiancheng/Hibernate/20101207/52757.html
session.merge ()方法对状态的变化
关于使用setId()后对象就成为托管状态,可以这么猜测:hibernate对我们new的实体类进行了管理。
针对该段代码将执行如下SQL语句:
Hibernate:
/* ①session.merge(userInfo2)的动作 */
select
userinfo0_.id as id0_0_,
userinfo0_.NAME as NAME0_0_,
userinfo0_.SEX as SEX0_0_,
userinfo0_.roomid as roomid0_0_
from
userinfo userinfo0_
where
userinfo0_.id=?
Hibernate:
/* ①session.merge(userInfo2)的动作 */
update
userinfo
set
NAME=?,
SEX=?,
roomid=?
where
id=?
session.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;
然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。
而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,
那其结果只会执行最后一个session.merge()方法所发出的update语句。
即使执行了session.merge()方法,UserInfo实体依然是脱管状态,
因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。
扩展阅读:
http://selvemen.iteye.com/blog/457225
2、我看merge()
merge的作用:对于一个对象(无论是否是新new的,还是处于游离态的):
如果数据库中有对应的ID,则会update;
如果没有,则会insert;
使用merge方法后,对对象之前的状态,不产生任何影响。
即:对象在使用merge()方法之前是什么状态,使用merge()方法后还是什么状态。
例子:
下面是当对象(str1)在第一个session关闭后,处于游离状态。
第二个session开启,又get或load一样的ID的数据出来时, 对那个游离态对象(str1),使用update肯定会出错,原因是持久层中已经有对象(str2),你的update会让那个游离态对象也变成持久态,两个持久态会冲突。
然而用merge的话,它会把第一个的对象数据赋值给已经处于持久化的那个对象中,而自己本身不得变为持久态;
===============================================
题外话题
hibernate部分字段更新的解决方案
在调用Hibernate的update方法时会更新对象的全部字段,若对象属性值为null,则相应的数据库字段也会被更新为空值。
通常的做法 是先将需要更新的对象加载上来,再将需要更新的属性值一个个的setter到对象中,但这样显然影响了代码的可读性,而且在使用 Struts2+hibernate进行开发时,页面传递参数后Struts2会将对象进行自动赋值,已经赋值的对象在更新前又要进行一次手动赋值再 update,这样明显散失去了sturts2的自动赋值的意义。
解决方法:
将需要更新的对象加载上来后,利用BeanUtils类的copyProperties方法,将需要更新的值copy到对象中,最后再调用update方法。
注 意:这里推荐使用的方法并非org.apache.comm*****.beanutils包中的方法,而是 org.springframework.beans.BeanUtils中的copyProperties方法。原因是Spring工具类提供了 copyProperties(source, target, ignoreProperties)方法,它能在复制对象值的时候忽略指定属性值,保护某些值不被恶意修改,从而更安全的进行对象的更新。此外,根据一些 测试结果spring中的copyProperties方法效率要高于apache的方法(这点未作进一步验证)。
参考代码:
Admin persistent = adminService.load(id);// 加载对象
BeanUtils.copyProperties(admin, persistent, new String[]{"id", "username"});// 复制对象属性值时忽略id、username属性,可避免username被恶意修改
adminService.update(persistent);// 更新对象
具体代码可参考SHOP++源代码。
以上为SHOP++技术教程。来源:http://www.shopxx.net
本文摘自:http://chinaxxren.javaeye.com/blog/834675
--
引用:
http://zhidao.baidu.com/question/469345066.html
http://blog.csdn.net/lang_man_xing/article/details/7572964
-
鉴于:hibernate是面向对象(实体、entity)操作,而不是某个对象的字段或属性。
鉴于:使用hibernate从数据库获取对象后,无需对数据库操作,而是直接操作获取的对象,hibernate就可以自动同步数据库。
因此:hibernate将对象分为三种状态,以便进行区分和管理:
1:瞬时/临时(Transient)
可以理解为该对象和hibernate一点关系也没有。
对该对象的操作不会和hibernate有任何联系或影响。
2:持久(Persistent)
使用hibernate对该对象进行管理,这会涉及到hibernate自动对数据库的相应的操作。
更细节的解释:
(hibernate通过对外提供session对象,和session对象的一系列方法,完成对数据的增删改查。hibernate自动对数据库的操作也是依赖于和session绑定)。
也就是说,在持久状态下,hibernate对对象的操作和seesion是分不开的。
3:脱管/游离(Detached)
这种状态是根据hibernate是否建立了session链接,以便与第2种状态进行区分。
可以理解为除了没有建立session(未连接数据库),其它的和第2种状态都一样。
hibernate已经对该对象进行绑定,并管理。只是没有建立session链接。
二、词汇定义
1:瞬时/临时(Transient) - 由new操作符创建,且尚未与Hibernate Session 关联的对象被认定为瞬时的。瞬时对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)。 如果瞬时对象在程序中没有被引用,它会被垃圾回收器销毁。
2:持久(Persistent) - 持久的实例在数据库中有对应的记录,并拥有一个持久化标识。 持久的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。 Hibernate会检测到处于持久状态的对象的任何改动,在当前操作单元执行完毕时将对象数据与数据库同步。开发者不需要手动执行UPDATE。
3:脱管/游离(Detached) - 与持久对象关联的Session被关闭后,对象就变为脱管的。 对脱管对象的引用依然有效,对象可继续被修改。脱管对象如果重新关联到某个新的Session上, 会再次转变为持久的,在脱管期间的改动将被持久化到数据库。
三、理解这三种状态的意义
便于使用hibernate提供的各种方法。意义是重大的。
比如:
merge()
session.close()对对象状态的影响
获取新的session后,对象状态,对数据库造成的影响。
四、讨论
说,这三种状态是hibernate的对象的生命周期,是不准确的。
因为每个状态都不是对象必须经过的。
但是这对象在这三种状态中可以相互转换。
就是状态。对象在hibernate中所表示的三种状态。
五、应用举例
1、关于merge方法
什么时候用?:
这个方法就是为在前台修改从后台读取的数据准备的。
【hibernate 需要设置为: hibernate update部分更新。因为直接使用merge()方法,会把数据库中有而传递过来的对象中没有的字段,会重置。这样就得在传参数时,把数据库中的字段都得写全。
具体参照:】
http://www.cnblogs.com/hyteddy/archive/2011/07/21/2113175.html
【其实,merge()方法解决了新new一个对象时,如何将其同步到数据库中去的问题。但是,需要把所有的字段写全,需要在前台页面中添加隐藏变量,这显然是不一个好方法。关于如何实现hibernate部分字段更新问题,请看这里(内容会拷贝到本文后面):】
http://www.rritw.com/a/JAVAbiancheng/Hibernate/20101207/52757.html
session.merge ()方法对状态的变化
public void run() { UserInfo userInfo = new UserInfo();//创建UserInfo实例 userInfo.setId(11112);//使之成为脱管状态 userInfo.setName("RW3"); userInfo.setSex("M"); UserInfo userInfo2 = new UserInfo();//创建UserInfo实例 userInfo2.setId(11112); //使之成为脱管状态 userInfo2.setName("RW4"); userInfo2.setSex("F"); Session session = HibernateSessionFactory.currentSession();//启动Session Transaction tx = session.beginTransaction();//启动事务 //调用merge方法,此时UserInfo实体状态并没有被持久化 //但是数据库中的记录被更新了 ①session.merge(userInfo); session.merge(userInfo2);//调用merge方法,此时UserInfo实体状态并没有被持久化 //merge方法与update方法的差别在于针对同样的操作update方法会报错 //原因在于update方法使得实体状态成为了持久化状态,而Session中不允许两个持久化实体有同样的持久化标识 ②//session.update(userInfo); //session.update(userInfo2); //以下两句不会发送SQL,因为userInfo2不是持久化状态的实体 ③userInfo2.setName("RW5"); userInfo2.setSex("M"); //提交事务 tx.commit(); //关闭Hibernate Session HibernateSessionFactory.closeSession(); }
关于使用setId()后对象就成为托管状态,可以这么猜测:hibernate对我们new的实体类进行了管理。
针对该段代码将执行如下SQL语句:
Hibernate:
/* ①session.merge(userInfo2)的动作 */
select
userinfo0_.id as id0_0_,
userinfo0_.NAME as NAME0_0_,
userinfo0_.SEX as SEX0_0_,
userinfo0_.roomid as roomid0_0_
from
userinfo userinfo0_
where
userinfo0_.id=?
Hibernate:
/* ①session.merge(userInfo2)的动作 */
update
userinfo
set
NAME=?,
SEX=?,
roomid=?
where
id=?
session.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;
然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。
而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,
那其结果只会执行最后一个session.merge()方法所发出的update语句。
即使执行了session.merge()方法,UserInfo实体依然是脱管状态,
因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。
扩展阅读:
http://selvemen.iteye.com/blog/457225
2、我看merge()
merge的作用:对于一个对象(无论是否是新new的,还是处于游离态的):
如果数据库中有对应的ID,则会update;
如果没有,则会insert;
使用merge方法后,对对象之前的状态,不产生任何影响。
即:对象在使用merge()方法之前是什么状态,使用merge()方法后还是什么状态。
例子:
下面是当对象(str1)在第一个session关闭后,处于游离状态。
第二个session开启,又get或load一样的ID的数据出来时, 对那个游离态对象(str1),使用update肯定会出错,原因是持久层中已经有对象(str2),你的update会让那个游离态对象也变成持久态,两个持久态会冲突。
然而用merge的话,它会把第一个的对象数据赋值给已经处于持久化的那个对象中,而自己本身不得变为持久态;
Session session1 = HibernateUtils.getSession(); Transaction transaction1 = session1.beginTransaction(); Students str1 = (Students)session1.get(Students.class, 2); transaction1.commit(); session1.clear(); session1.close();//session关闭,str1为游离态(detached) Session session2 = HibernateUtils.getSession(); Transaction transaction2 = session2.beginTransaction(); Students str2 = (Students)session2.get(Students.class, 2); str1.setName("wer"); session2.merge(str1);//更新数据库 System.out.println(str2.getName()); //这里改变了。因为str2是持久状态的。 str2.setName("ee"); System.out.println(str1.getName()); //这里不会改变,说明对str1使用merge()后没有被持久化; transaction2.commit(); session2.clear(); session2.close();
===============================================
题外话题
hibernate部分字段更新的解决方案
在调用Hibernate的update方法时会更新对象的全部字段,若对象属性值为null,则相应的数据库字段也会被更新为空值。
通常的做法 是先将需要更新的对象加载上来,再将需要更新的属性值一个个的setter到对象中,但这样显然影响了代码的可读性,而且在使用 Struts2+hibernate进行开发时,页面传递参数后Struts2会将对象进行自动赋值,已经赋值的对象在更新前又要进行一次手动赋值再 update,这样明显散失去了sturts2的自动赋值的意义。
解决方法:
将需要更新的对象加载上来后,利用BeanUtils类的copyProperties方法,将需要更新的值copy到对象中,最后再调用update方法。
注 意:这里推荐使用的方法并非org.apache.comm*****.beanutils包中的方法,而是 org.springframework.beans.BeanUtils中的copyProperties方法。原因是Spring工具类提供了 copyProperties(source, target, ignoreProperties)方法,它能在复制对象值的时候忽略指定属性值,保护某些值不被恶意修改,从而更安全的进行对象的更新。此外,根据一些 测试结果spring中的copyProperties方法效率要高于apache的方法(这点未作进一步验证)。
参考代码:
Admin persistent = adminService.load(id);// 加载对象
BeanUtils.copyProperties(admin, persistent, new String[]{"id", "username"});// 复制对象属性值时忽略id、username属性,可避免username被恶意修改
adminService.update(persistent);// 更新对象
具体代码可参考SHOP++源代码。
以上为SHOP++技术教程。来源:http://www.shopxx.net
本文摘自:http://chinaxxren.javaeye.com/blog/834675
--
引用:
http://zhidao.baidu.com/question/469345066.html
http://blog.csdn.net/lang_man_xing/article/details/7572964
-
发表评论
-
Spring之Interceptor之path patterns路径匹配规则
2018-12-26 11:20 8776Spring之Interceptor之path pattern ... -
Spring4.X之Constructor Injection 构造方法注入
2018-12-24 17:37 1574Spring4.X之Constructor Injection ... -
SpringMVC之@RequestMapping @ResponseBody 和 @RequestBody 注解的用法
2018-05-30 10:55 15811、@RequestMapping @RequestMappi ... -
Spring4.X之Bean的Scope
2017-11-06 16:29 1201https://docs.spring.io/spring/d ... -
Spring4.X之基于Java注解的配置(与SpringBoot的诞生)
2017-11-02 16:57 4150最近项目用到了SpringBoot,对其没有xml配置就可以运 ... -
03 - SpringBoot: Building a RESTful Web Service
2017-09-25 17:47 1025Building a RESTful Web Service ... -
02 - Difference between spring @Controller and @RestController annotation
2017-09-25 17:04 890Difference between spring @Con ... -
01 -Spring Framework: @RestController vs. @Controller
2017-09-25 16:45 746Spring MVC Framework and REST ... -
Spring - MVC 思维导图,让Spring不再难懂
2017-08-09 03:21 1080引用: http://www.iteye.com/news/3 ... -
hibernate merge与update区别
2017-04-18 15:38 2196今天做了个测试,写了 ... -
Struts2拦截器原理以及实例
2017-02-15 12:49 474Struts2拦截器原理以及实例 http://www.cnb ... -
SSH之Struts2 VS. SpringMVC
2017-02-07 10:26 996Struts 2 vs SpringMVC - Battl ... -
Maven之POM之SSH之libs之configuration
2017-02-05 08:56 782Maven repo libs: Servlet API, ... -
Hibernate自定义查询
2014-02-24 16:29 1584public void addCarmera(Carmera ... -
通过配置struts.xml解决 struts2和 dwr兼容的问题
2012-11-20 10:20 2079众所周知,strust2 通过在 web.xml中配置 fil ...
相关推荐
**hibernate的生命周期** ...总之,理解并熟练掌握Hibernate对象的生命周期,对于编写高效、可靠的Java应用程序至关重要。正确管理对象状态,合理使用生命周期方法,能帮助我们避免不必要的数据库操作,提升应用性能。
本示例将深入探讨Hibernate Session的生命周期及其使用,帮助你更好地理解和运用这个强大的工具。 Hibernate Session是Hibernate的核心接口,它是与数据库交互的主要接口。Session对象负责管理实体对象的状态,包括...
Hibernate的核心概念之一就是持久化对象的生命周期,这涉及到对象在数据库中的状态及其与Session的关系。 首先,我们来看一下Hibernate中持久化对象的三种基本状态: 1. **瞬时对象(Transient Objects)**: - ...
总结,理解Hibernate3.2中的对象生命周期是有效使用Hibernate的关键。正确管理对象状态,能够避免数据丢失,提高应用程序性能,并减少潜在的并发问题。深入源码和使用专业工具能进一步提升开发效率。
本文将深入探讨Hibernate中的持久化对象生命周期,包括瞬时对象、持久化对象和游离对象的状态转换及其特性。 1. 瞬时对象(Transient Objects) 瞬时对象是指通过`new`操作符创建但尚未与数据库记录关联的Java对象...
在IT行业中,尤其是在Java开发领域,实体对象的生命周期管理是至关重要的一个环节,尤其是在使用ORM(Object-Relational Mapping)框架如Hibernate时。本文将详细探讨“测试实体对象的生命周期”,并结合给定的标签...
这些状态决定了对象与数据库之间的关联程度,以及Hibernate如何处理对象的生命周期。以下是Hibernate对象的三种主要状态及其特点: 1) 临时状态(Transient State): 当通过`new`关键字创建一个新的对象时,该对象...
9. **生命周期方法**:在某些编程语言和框架中,领域对象可能包含一些生命周期方法,如 `save()`、`delete()`、`load()` 等,用于操作对象的生命周期。 10. **CQRS(命令查询责任分离)**:在复杂系统中,CQRS 模式...
8. Hibernate对象生命周期: - Hibernate管理的对象生命周期包括瞬时态(Transient)、持久态(Persistent)、托管态(Managed)、脱管态(Detached)和删除态(Removed)。 以上就是“Hibernate考试题.pdf”中...
在Hibernate中,通过`@ManyToOne`或`@OneToOne`注解表示,但需要注意的是,聚合关系通常不会影响对象的生命周期。 这些关系模型在Hibernate中通过注解或者XML配置文件进行定义,以实现Java对象和数据库记录之间的...
Hibernate允许开发者定义对象的生命周期回调方法,如preInsert()、postInsert()、preUpdate()等,以便在对象状态改变时执行特定的业务逻辑。 **九、懒加载与立即加载** 懒加载(Lazy Loading)是一种优化策略,只在...
在Hibernate中,对象的生命周期包括瞬时态、托管态、持久态和脱管态。通过Hibernate,我们可以轻松地将对象从内存中保存到数据库,或者从数据库中加载到内存。 **三、Hibernate配置** 使用Hibernate,首先需要配置...
1. **持久化对象的生命周期**:在Hibernate中,对象经历了临时态、持久态和游离态三个状态。临时态的对象没有与Session关联,数据未保存到数据库;持久态对象已与Session绑定,其状态会随Session的提交而保存到...
一旦对象变为持久态,Hibernate会负责它的生命周期管理,包括插入、更新和删除操作。 二、一对一(OneToOne)关系映射 在数据库设计中,一对一关系意味着两个实体表之间存在唯一映射。在Hibernate中,可以通过@...
在 Hibernate 框架中,Java 对象...开发者应合理管理 Session 生命周期,避免并发问题,确保数据的一致性和完整性。同时,根据具体应用需求,选择合适的缓存清理策略和对象状态转换时机,以达到最佳的数据库操作效果。
6. **实体生命周期管理**:Hibernate自动管理对象的状态,包括瞬态、持久化、托管和脱管四种状态,以及它们之间的转换。 7. **多对一、一对多、多对多关系映射**:Hibernate支持复杂的关联关系映射,如单向关联、...
23.1.1 Session对象的生命周期与本地线程绑定 23.1.2 Session对象的生命周期与JTA事务绑定 23.2 实现对话 23.2.1 使用游离对象 23.2.2 使用手工清理缓存模式下的Session 23.3 小结 23.4 思考题 第24章...