叙:之前介绍了持久化、持久化类的相关信息,关于持久化类只讲了相关编写规则等(文章地址:https://www.cnblogs.com/Email-qtl777777/p/9650239.html),关于其内部的更多的划分并没进行细讲,本章电虫就持久化类的三个状态以及三种状态的区分以及三种状态的区分进行学习、记录;
持久化类的三种状态
Hibernate是持久层框架,通过持久化的类完成ORM(Java对象和数据库表的映射关系)操作;hibernate为更好地管理持久化类的状态,特此将持久化类分成三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(脱管状态),这三种状态的名称并不是固定的,就比如脱管态有的叫做托管态、离线态等,并不影响本章的学习和以后大家的使用;
持久化类三态的介绍:
- 瞬时态(transient):一般是对象刚被创建出来的,没有自己的唯一性标识OID(与表的主键对应的对象属性),而且不被seeeion所管理;
- 持久态(persistent):有自己的唯一性标识OID,并且被session所管理,一般是对象被保存的状态;持久态是三态中的重点,因为持久化类的持久态的对象可以自动更新数据库。
- 脱管态(detached):有自己的唯一性标识OID,但是没有session对其进行管理,一般是对象被保存后,session被销毁的状态;
三种状态的区分:
光用嘴说还是有点不够到位,通过查看下列的代码以及代码注释就会一目了然;
@Test // 三态展示 public void demo1(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); Customer c = new Customer(); //瞬时态 c.setCust_name("BBQ"); Serializable id = session.save(c);//持久态 System.out.println("它的ID是:"+id); bt.commit(); session.close(); System.out.println("名称是"+c.getCust_name());//脱管态 }
- 从
Customer c = new Customer();//瞬时态
看出,这个对象C刚被new创建出来,没有任何信息,没有唯一性标识、没有session管理; - 从
Serializable id = session.save(c);//持久态
此时对象c已经被save()方法保存到数据库中了,因此有了自己的主键(默认生成),并且是由session来进行管理着的,所以此时对象c是持久态的,serialiazble id这个是获得c对象的主键信息的,在下方打印出来id的值可以看到c对象的id; - 从
System.out.println("名称是"+c.getCust_name());//脱管态
看出,此时c对象已经没有了session(上一步已经被销毁了),但是这个c对象已经永久性的有了自己的唯一性标识,因此,此时的c对象是脱管态;
持久化类的三种状态转换
先看转换图在自己脑中有一个大概的构思;
现在根据图以及之前的三态具有哪些自己的特性,进行分析:
瞬时态对象
瞬时态的获得
通过new一个新的对象,例如:Customer C = new Customer();
状态的转换
- 瞬时态 —> 持久态
瞬时态和持久态区别在于瞬时态没有session管理以及没有OID,持久态有,因此使用保存方法时这个对象就会被session所管理并且保存后会被自动设置上OID;
使用save((Object object)、saveOrUpdate(Object object)的保存方法即可,例如:Serializable id = session.save(c);
- 瞬时态 —> 脱管态
瞬时态和脱管态的区别在于,瞬时态没有OID而脱管态有,因此手动给瞬时态添加一个OID即可使之变成一个脱管态;
使用c.setCust_id(1l);即可;
持久态对象
持久态的获得
通过查询的方法直接获得持久态对象,例如:get()、load()、find()、intreate()等方法直接获得一个持久态对象;
状态的转换
- 持久态 —> 瞬时态
直接删除对象即可,使用delect()方法,例:session.delect();
- 持久态 —> 脱管态
持久态和脱管态的区别是,持久态有session进行管理,所以将持久态的session清理掉即可,使用的方法有:close()、clear()、evicet()等方式,clear()和evicet()方法均是清理数据,clear()是清理所有数据,evicet()是清理单条数据;使用方法–例如:session.close();
脱管态对象
脱管态的获得
脱管态是只有OID,没有session管理,因此可以在创建完对象后直接赋给对象OID值;
例如:Customer C = new Customer(); C.setCust_id(3l);
状态转换
- 脱管态 —> 持久态
使用更新操作来获得,例如save()、saveOrUpdate();
session.save(Object obj);
- 脱管态 —> 瞬时态
直接将对象的OID属性设置成null,例:C.setCuest_id(null);
持久态对象自动更新数据库(重点)
三态的学习中持久态是最重要的一个,而他之所以重要的原因就是因为持久态对象可以自动更新数据库,也就是说持久态对象在设置好更新数据的内容后并不需要update()方法进行手动设置更新,他会自动保存,代码如下,可以参照代码更容易理解;
@Test // 持久态对象可以自动更新数据库 public void demo2(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); Customer customer = session.get(Customer.class, 8l); customer.setCust_name("?FBI"); bt.commit(); session.close(); }
在进行demo操作时,先查看数据库Customer表中id为8的Cust_name的数据(我的实体类的各个属性名和实体类映射的数据表中的列明一致,可以直接这么看),然后运行demo后再次查看后Cust_name的值,发现其值已经发现变化了,由此说明持久化对象可以自动更新数据库;
注意:当修改的值与数据库表中的数据不一致时才会实现更新操作,若是一致则系统智能的省略更新操作,只进行查询;
持久态之所以能自动更新是依靠了hibernate一级缓存,更准确的说是一级缓存中的快照区这个特殊的区;
持久化类(初步):https://www.cnblogs.com/Email-qtl777777/p/9650239.html
pass:hibernate的一级缓存会在后边进行学习记录;
《本章完》
原文地址:https://www.cnblogs.com/Email-qtl777777/p/9650352.html