Hibernate中的对象有3种状态,瞬时对象(TransientObjects)、持久化对象(PersistentObjects)和离线对象(DetachedObjects也叫做脱管对象)。这三个状态的主要区别在两方面:1、session;2、数据库
下面说一下不同状态的特征:
1、Transient (瞬态)
a) 不在Session的缓存中,不与任何的Session实例相关联。
b) 在数据库中没有与之相对应的记录<span style="font-size:14px;">User user = new User();
user.setName("姓名");
user.setAge("年龄");</span>
通过Session的save()方法和saveOrUpdate()方法可以把一个临时对象和数据库相关联,并把临时对象携带的信息通过配置文件所做的映射插入数据库中,这个临时对象就成为持久化对象。
2、Persistent(持久态)
a) 在Session的缓存中,与Session实例相关联。
b) 在数据库中存在与之相对应的记录。
通过Session对象的save()方法进行保存处于瞬时态的对象后,该对象就变为持久态。此时Session中已经存在该对象,并且对应数据库中的一条记录。
<span style="font-size:14px;"> </span><span style="font-size:18px;">SessionFactory sessionFactory = config.buildSessionFactory(); Session session = sessionFactory.getCurrentSession(); Transaction tx = session.beginTransaction(); User user = new User(); user.setName("姓名"); user.setAge("年龄"); session.save(user); tx.commit(); </span>在调用save()方法后,持久化对象user就变为持久态,但是执行了commit()方法之后,数据库操作才会进行。
3、Detached(游离态或脱管态)
a) 不在Session的缓存中,不与任何的Session实例相关联
b) 在数据库中存在与之相对应的记录。(前提条件是没有其他Session实例删除该条记录)。
脱管对象虽然拥有用户的标识id,所以通过update()、saveOrUpdate()等方法,再次与持久层关联。
二、session的get和load的区别
我们在说这三态是引入了session,那为什么要用它呢?
1、减少访问数据库的频率,可以提高数据库访问的性能。
2、保证缓存中的对象与数据库中的相关记录保持同步。
3、当缓存中的持久化对象(位于缓存中的对象)之间存在循环关联关系时,Sessioin会保证不出现访问对象的死循环。
get和load最大的区别,就是用get方法执行查询,会在执行get时马上查出,而load呢则是什么时候需要这些数据才会进行查询,也就是说load的特点是延迟加载。lazy是通过实现代理对象实现,代理对象主要采用的是CGLIB库生成的,采用的是继承方式。不同于JDK中的代理。
另外,这两个方法的区别就是:如果查询的数据为空,那么get方式返回null,而load方式会抛出ObjectNotFoundException异常