站在持久化的角度, Hibernate 把对象分为 4 种状态:

      1. 持久化状态

      2. 临时状态

      3. 游离状态

      4. 删除状态

    Session 的特定方法能使对象从一个状态转换到另一个状态.

    下面是各状态之间的转换图, 以及如何转换的:

准备工作:

  1. 建立持久化类

    Person类

  1. package com.hibernate.entities;
  2.  
  3. public class Person {
  4.  
  5. private Integer id;
  6. private String name;
  7. private Integer age;
  8.  
  9. public Person() {
  10. super();
  11. }
  12.  
  13. public Person(String name, Integer age) {
  14. super();
  15. this.name = name;
  16. this.age = age;
  17. }
  18.  
  19. public Integer getId() {
  20. return id;
  21. }
  22.  
  23. public void setId(Integer id) {
  24. this.id = id;
  25. }
  26.  
  27. public String getName() {
  28. return name;
  29. }
  30.  
  31. public void setName(String name) {
  32. this.name = name;
  33. }
  34.  
  35. public Integer getAge() {
  36. return age;
  37. }
  38.  
  39. public void setAge(Integer age) {
  40. this.age = age;
  41. }
  42.  
  43. }

  2. 建立持久化类的映射文件

    Person.hbm.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <hibernate-mapping>
  5. <class name="com.hibernate.entities.Person" table="PERSONS">
  6. <id name="id" type="java.lang.Integer">
  7. <column name="ID" />
  8. <generator class="identity" />
  9. </id>
  10. <property name="name" type="java.lang.String">
  11. <column name="NAME" />
  12. </property>
  13. <property name="age" type="java.lang.Integer">
  14. <column name="AGE" />
  15. </property>
  16. </class>
  17. </hibernate-mapping>

  3. 建立Hibernate的主配置文件 hibernate.cfg.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-configuration PUBLIC
  3. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  5. <hibernate-configuration>
  6. <session-factory>
  7.  
  8. <!-- 配置连接数据库的信息 -->
  9. <property name="hibernate.connection.username">root</property>
  10. <property name="hibernate.connection.password">oracle</property>
  11. <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
  12. <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  13.  
  14. <!-- 配置数据库方言 -->
  15. <property name="hibernate.dialect">org.hibernate.dialect.MySQL57InnoDBDialect</property>
  16.  
  17. <!-- 设置数据表生成策略 -->
  18. <property name="hibernate.hbm2ddl.auto">update</property>
  19.  
  20. <!-- 是否格式化SQL -->
  21. <property name="hibernate.format_sql">true</property>
  22.  
  23. <!-- 是否显示SQL -->
  24. <property name="hibernate.show_sql">true</property>
  25.  
  26. <!-- 修改delete()的默认行为, 使删除对象的OID变为null -->
  27. <property name="hibernate.use_identifier_rollback">true</property>
  28.  
  29. <!-- 添加配置文件 -->
  30. <mapping resource="com/hibernate/entities/Person.hbm.xml"/>
  31.  
  32. </session-factory>
  33. </hibernate-configuration>

  4. 建立单元测试类

  1. package com.test;
  2.  
  3. import org.hibernate.Session;
  4. import org.hibernate.SessionFactory;
  5. import org.hibernate.Transaction;
  6. import org.hibernate.annotations.SelectBeforeUpdate;
  7. import org.hibernate.cfg.Configuration;
  8. import org.junit.After;
  9. import org.junit.Before;
  10. import org.junit.Test;
  11.  
  12. public class TestHibernate {
  13.  
  14. private SessionFactory sessionFactory;
  15. private Session session;
  16. private Transaction transaction;
  17.  
  18. @Before
  19. public void init(){
  20.  
  21. sessionFactory = new Configuration().configure().buildSessionFactory();
  22. session = sessionFactory.openSession();
  23. transaction = session.beginTransaction();
  24. }
  25.  
  26. @After
  27. public void distory(){
  28. transaction.commit();
  29. session.close();
  30. sessionFactory.close();
  31. }
  32. }

  这里我直接把注释, 说明等文字写在代码里了,可以直接复制下来, 放到IDE开发工具里面慢慢看

  1. package com.test;
  2.  
  3. import org.hibernate.Session;
  4. import org.hibernate.SessionFactory;
  5. import org.hibernate.Transaction;
  6. import org.hibernate.annotations.SelectBeforeUpdate;
  7. import org.hibernate.cfg.Configuration;
  8. import org.junit.After;
  9. import org.junit.Before;
  10. import org.junit.Test;
  11.  
  12. import com.hibernate.entities.Person;
  13.  
  14. public class TestHibernate {
  15.  
  16. private SessionFactory sessionFactory;
  17. private Session session;
  18. private Transaction transaction;
  19.  
  20. @Before
  21. public void init(){
  22.  
  23. sessionFactory = new Configuration().configure().buildSessionFactory();
  24. session = sessionFactory.openSession();
  25. transaction = session.beginTransaction();
  26. }
  27.  
  28. @After
  29. public void distory(){
  30. transaction.commit();
  31. session.close();
  32. sessionFactory.close();
  33. }
  34.  
  35. /*
  36. * 站在持久化的角度:
  37. * Hibernate 把对象分为 4 种状态:
  38. * 持久化状态, 临时状态, 游离状态, 删除状态.
  39. * Session 的特定方法能使对象从一个状态转换到另一个状态.
  40. */
  41. /*
  42. * 一: 临时对象(Transient)
  43. * 1. 在使用代理主键的情况下, OID 通常为 null
  44. * 2. 不处于 Session 的缓存中
  45. * 3. 在数据库中没有对应的记录
  46. */
  47. /*
  48. * 二: 持久化对象(也叫"托管")(Persist)
  49. * 1. OID 不为 null.
  50. * 2. 位于Session缓存中.
  51. * 3. 若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应.
  52. * 4. Session在flush缓存时, 会根据持久化对象的属性变化, 来同步更新数据库.
  53. * 5. 在同一个Session实例缓存中, 数据库表中的每条记录只对应唯一的持久化对象.
  54. */
  55. /*
  56. * 三: 删除对象(Removed)
  57. * 1. 在数据库中没有和其OID对应的记录.
  58. * 2. 不再处于Session缓存中.
  59. * 3. 一般情况下, 应用程序不再使用该对象.
  60. */
  61. /*
  62. * 四: 游离对象(也叫"托管")(Detached)
  63. * 1. OID不为null.
  64. * 2. 不再处于Session缓存中.
  65. * 3. 一般情况下, 游离对象是持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录.
  66. */
  67.  
  68. /**
  69. * save()方法:使一个临时对象转变为持久化对象.
  70. * 执行save()方法时, 系统会完成以下操作:
  71. * 1. 把 new 对象加入到Session缓存中, 使它进入持久化状态.
  72. * 2. 选用映射文件指定的标示符生成器, 为持久化对象分配唯一的OID.
  73. * 在使用中代理主键的情况下, setId() 方法为 new 对象设置的OID 是无效的.
  74. * 3. 计划执行一条 insert 语句(在flush缓存的时候).
  75. * persist()方法: 同save()方法.
  76. */
  77. @Test
  78. public void testSaveOrPersist(){
  79.  
  80. // 保存一个对象
  81. // Person person = new Person("Tom", 12);
  82. // session.save(person);
  83.  
  84. // 使用 save() 保存一个有id值的对象时, 正常保存.
  85. // Person person = new Person("Tom", 12);
  86. // person.setId(100);
  87. // session.save(person);
  88.  
  89. // 使用 persist()保存一个有id值得对象时, 抛异常!
  90. // Person person = new Person("Mike", 23);
  91. // person.setId(100);
  92. // session.persist(person);
  93.  
  94. // 试图修改持久化对象的 ID, 不允许!
  95. // Person person = session.get(Person.class, 1);
  96. // person.setId(1000);
  97. // session.update(person);
  98.  
  99. }
  100.  
  101. /**
  102. * get() 和 load() 方法
  103. * 相同点:
  104. * 都可以根据指定的OID, 从数据库中加载一个持久化对象.
  105. * 不通电:
  106. * 1. 当数据库不存在OID对应的记录时:
  107. * load() 会抛出异常.
  108. * get() 返回null.
  109. * 2. 两者采用不同的加载策略:
  110. * load() 支持延迟加载.
  111. * get() 不支持.
  112. */
  113. @Test
  114. public void testGetOrLoad(){
  115.  
  116. // 1. 使用 get() 获取对象
  117. // 当调用 get() 时, Hibernate会计划执行SQL, 在flush时的时候, 会发送SQL语句.
  118. // session.get(Person.class, 2);
  119. // session.flush();
  120. // System.out.println("======================");
  121.  
  122. // 2. 使用 load() 延迟加载对象
  123. // 当调用 load() 时, Hibernate不会计划执行SQL
  124. // 即使flush操作的时候, 如果没有使用这个对象, 那么Hibernate就不会发送SQL语句.
  125. // 只有在使用这个对象的时候, Hiberante才会发送SQL语句. 这就是延迟加载!
  126. Person person = session.load(Person.class, 2);
  127. session.flush();
  128. System.out.println("======================");
  129. System.out.println(person.getName());
  130.  
  131. }
  132.  
  133. /**
  134. * 1. update(): 使一个游离对象转变为持久化对象, 并且计划执行一条SQL语句.
  135. * 2. 如果希望Session仅当修改了 new 对象的属性时, 才执行 update 语句
  136. * 可以把映射文件中的<class>元素的 select-before-update 设置为true, 默认为false.
  137. * 3. 当 update() 关联一个游离对象时, 如果在Session的缓存中已经存在相同OID的持久化对象, 会抛异常!
  138. * 4. 当 update() 关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常!
  139. */
  140. @Test
  141. public void testUpdate(){
  142.  
  143. // 一: 正常的 update
  144. // // tip:游离对象是由持久化对象转换过来的.
  145. // Person person = session.get(Person.class, 1);
  146. // transaction.commit();
  147. // // session 关闭后, person 对象转换为游离对象.
  148. // session.close();
  149. // session = sessionFactory.openSession();
  150. // transaction = session.beginTransaction();
  151. // person.setAge(19);
  152. // // 执行完 update, person对象由游离对象转变为持久化对象.
  153. // session.update(person);
  154.  
  155. // 二: 当在配置文件添加 select-before-update=true 的时候
  156. // 这里我们用注释来做, 在类上加上: @SelectBeforeUpdate(value=true)
  157. // 1. 没有改变任何属性, 当时Hibernate仍然发送一条SQL语句来验证属性值是否改变.
  158. // Person person = session.get(Person.class, 1);
  159. // session.update(person);
  160. // 2. 改变了属性之后, 不仅发送一条SQL语句, 还会发送一条update语句.
  161. // Person person = session.get(Person.class, 1);
  162. // person.setName("Kim");
  163. // session.update(person);
  164.  
  165. // 三: Session缓存中存在相同的OID.
  166. // // 先获取一个持久化Person, 然后关闭Session变为游离态.
  167. // Person person1 = session.get(Person.class, 1);
  168. // transaction.commit();
  169. // session.close();
  170. // session = sessionFactory.openSession();
  171. // transaction = session.beginTransaction();
  172. // // 开启Session, 再获取一个相同的Person对象
  173. // Person person2 = session.get(Person.class, 1);
  174. // person1.setName("Sunny");
  175. // // 把游离态的person1转化为持久化态, 由于我们缓存中已经有一个OID为1的person2
  176. // // 所以抛异常!(Hibernate不允许缓存中存在OID相同的对象)
  177. // session.update(person1);
  178.  
  179. // 四: 数据库中不存在相应的记录
  180. // 意味着这是一个临时对象, 或者删除对象
  181. // 只能执行save()或者persist()进行持久化
  182. // update() 只能把游离对象, 转化为持久化对象
  183. // Person person = new Person("Lily", 15);
  184. // // 抛异常!
  185. // session.update(person);
  186.  
  187. }
  188.  
  189. /**
  190. * saveOrUpdate(): 包含了 save() 和 update() 的功能
  191. * 如果是一个临时对象, 就执行save()
  192. * 如果是一个持久化对象, 就执行update()
  193. * 判断是临时对象的标准:
  194. * 1. 如果对象的OID为null.
  195. * 2. 映射文件中<id> 设置了 unsaved-value 属性,
  196. * 并且java对象的OID取值与这个unsaved-value属性值匹配.
  197. */
  198. @Test
  199. public void testSaveOrUpdate(){
  200.  
  201. // id(OID)值为null, 执行 insert 语句
  202. // Person person = new Person("Mike", 15);
  203. // session.saveOrUpdate(person);
  204.  
  205. // id(OID)值为unsaved-value的值(100), 执行insert语句
  206. // Person person = new Person("Mike", 15);
  207. // person.setId(100);
  208. // session.saveOrUpdate(person);
  209.  
  210. // 数据库中有与id(OID)值对应的值, 那么就执行update语句
  211. Person person = new Person("Mike", 15);
  212. // 数据库中有主键为2的数据, 执行update语句
  213. person.setId(2);
  214. session.saveOrUpdate(person);
  215.  
  216. }
  217.  
  218. /**
  219. * merge()
  220. */
  221. @Test
  222. public void testMerge(){
  223.  
  224. /*
  225. * 一: 临时对象
  226. * 创建一个新的News对象,把new1对象的属性拷贝到新建的News对象中
  227. * 持久化这个News对象,计划执行一条insert语句
  228. */
  229. // Person person = new Person("Tom", 13);
  230. // // 发送了一条insert
  231. // session.merge(person);
  232.  
  233. /*
  234. * 二: 游离对象 + 存在Session缓存中
  235. */
  236. // Person person1 = session.get(Person.class, 1);
  237. // // guanbiSession, 开启Session使对象变为游离态
  238. // transaction.commit();
  239. // session.close();
  240. // session = sessionFactory.openSession();
  241. // transaction = session.beginTransaction();
  242. // // 重新加载到Session缓存中.
  243. // Person person2 = session.get(Person.class, 1);
  244. // person1.setName("Mike");
  245. // // 把person1对象的属性拷贝到person2持久化对象中,计划执行一条update语句
  246. // // 发送了2条select, 1条update
  247. // session.merge(person1);
  248.  
  249. /*
  250. * 三: 游离对象 + 不存在Session缓存中 + 数据库中存在id为1的记录
  251. */
  252. // Person person = session.get(Person.class, 1);
  253. // transaction.commit();
  254. // session.close();
  255. // session = sessionFactory.openSession();
  256. // transaction = session.beginTransaction();
  257. // person.setName("Kim");
  258. // // 从数据库加载id为1的News持久化对象(会发送一条select)
  259. // // 把person对象的属性拷贝到News持久化对象中,计划执行一条update语句
  260. // // 发送了2条select, 1条update
  261. // session.merge(person);
  262.  
  263. /*
  264. * 四: 游离对象 + 不存在Session缓存中 + 数据库中不存在id为1的记录
  265. */
  266. // // 1 条select
  267. // Person person = session.get(Person.class, 1);
  268. // // 从数据库中删除, 1 条delete
  269. // session.delete(person);
  270. // transaction.commit();
  271. // session.close();
  272. // session = sessionFactory.openSession();
  273. // transaction = session.beginTransaction();
  274. // // 1 一条insert
  275. // session.merge(person);
  276.  
  277. }
  278.  
  279. /**
  280. * delete(): 既可以删除一个游离对象, 也可以删除一个持久化对象
  281. * 处理过程:
  282. * 1. 计划执行一条 delete 语句
  283. * 2. 把对象从 Session缓存中移除, 该对象进入删除状态
  284. * hibernate.use_identifier_rollback 属性:
  285. * 这个值默认为false, 如果改为true, 将改变 delete()的运行行为,
  286. * delete()会把持久化对象或游离对象的OID置为null, 使它们变为临时对象
  287. */
  288. @Test
  289. public void testDelete(){
  290.  
  291. // 1. hibernate.use_identifier_rollback=false
  292. // Person person = session.get(Person.class, 3);
  293. // session.delete(person);
  294. // session.flush();
  295. // // 打印 3
  296. // System.out.println(person.getId());
  297.  
  298. // 2. hibernate.use_identifier_rollback=true
  299. Person person = session.get(Person.class, 3);
  300. session.delete(person);
  301. session.flush();
  302. // 打印 null
  303. System.out.println(person.getId());
  304.  
  305. }
  306.  
  307. }

Hibernate对象的状态的更多相关文章

  1. Hibernate对象的状态和映射

    一. Hibernate对象的状态 实体对象的三种状态: 1) 暂态(瞬时态)(Transient)---实体在内存中的自由存在,它与数据库的记录无关. po在DB中无记录(无副本),po和sessi ...

  2. Hibernate(3)——实例总结Hibernate对象的状态和ThreadLoacl封闭的session

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: Hibernate的内部执行过程(CRUD) 对象的状态及其转换图和例子 使用JUnit测试 使用getCur ...

  3. Hibernate对象的状态分类

    对象的状态: 临时状态Transient: 与数据库没有对应,跟Session没有关联 一般是新new出的对象 持久化状态Persistent: 对象在Session的管理之中,最终会有对应的数据库记 ...

  4. Hibernate对象的状态转换

    Hibernate中的实体对象可以分为三种状态:Transient(临时).Persistent(持久).Detached(游离) Transient 用new创建出对象,这些对象还没有与数据库发生任 ...

  5. hibernate对象的状态以及生命周期

    瞬时状态:session中没有,数据库中没有 持久状态:session中有,数据库中有 游离状态:session中没有,数据库中有 get和load都是用来提取数据的 get和load的区别: get ...

  6. 菜鸟学SSH(八)——Hibernate对象的三种状态

    前面写了几篇关于SSH的博客,但不是Struts就是Spring,Hibernate还从来没写过呢.说好是SSH的,怎么可以光写那两个,而不写Hibernate呢对吧.今天就先说说Hibernate对 ...

  7. hibernate对象的三种状态

    对于hibernate,我想不在这里讲解了,我们就直接进入主题 在这里我将要说的是"hibernate对象的三种状态",对象是我们十分熟悉的,对吧!而对于对象它有三种状态 分别是瞬 ...

  8. hibernate对象三种状态

    在Hibernate中,对象有三种状态:临 时状态(Transient).持久状态(Persistent)和游离状态(Detached). 处于持久态的对象也称为 PO(PersistenceObje ...

  9. [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. Javascript的delete

    Javascript中的激活对象(Activation object)和变量对象(Variable object):每个执行上下文在其内部都有一个Variable Object.与执行上下文类似,Va ...

  2. JSP 动作元素

    JSP动作元素 1.  动作元素分类 用来动态的包含文件.网页跳转及使用JavaBean组件等. 语法:<jsp:XXX />或者<jsp:XXX></jsp:XXX&g ...

  3. maven遇到的问题

    1.Missing artifact net.sf.json-lib:json-lib:jar:2.4:compile pom.xml原内容: <dependency> <group ...

  4. nginx+tomcat集群配置(4)--rewrite规则和多应用根目录设定思路

    前言: nginx中有一块很重要的概念, 就是rewrite规则. 它会对URL进行修改, 然后进行内部的重定向. rewrite授予了nginx更多的自由, 使得后级服务的接入更加地方便. 本文将简 ...

  5. TCP状态变迁流程

    主动建立TCP链接情况: 被动建立TCP链接情况 主动断开链接的情况 被动断开连接的情况 在TIME_WAIT阶段需要停留2倍的MSL,MSL即Maximum Segment Lifetime,表示任 ...

  6. [dijkstra+heap优化] 模板

    var n,m,s,i,j,x,y,z,l,tot :longint; pre,last,other,len :..] of longint; heap,d,pl :Array[..] of long ...

  7. Lua与C++相互调用

    {--1.环境--} 为了快速入手,使用了小巧快速的vc++6.0编译器 以及在官网下载了Lua安装包..官网地址{--http://10.21.210.18/seeyon/index.jsp--} ...

  8. C#委拖小例子

    委托具有以下属性: 委托类似于 C++ 函数指针,但它们是类型安全的. 委托允许将方法作为参数进行传递. 委托可用于定义回调方法. 委托可以链接在一起:例如,可以对一个事件调用多个方法. 方法不必与委 ...

  9. mac10.9下eclipse的storm开发环境搭建

    --------------------------------------- 博文作者:迦壹 博客地址:http://idoall.org/home.php?mod=space&uid=1& ...

  10. 使用swipecard实现卡片视图左右滑动监听以及点击监听

     前言: 大家好,今天给大家介绍安卓一种特别实用有很酷炫的组件swipecard,当然这并不是安卓爸爸创造的,这是国内的一个我认为是大牛的一个人随便写着玩儿搞出来了,我看了他的代码介绍已经很清晰了,但 ...