User user = session.get(User.class, "1");
如上调用get方法后,会向数据库查询id为1的user。
User user = session.load(User.class, "1");
如上调用load方法后,会返回一个代理对象,id为1,但其他属性都为null,并未向数据库查询。若继续执行String name = user.getName();
,则才会执行数据库的查询。而在此时,很有可能数据库中根本没有id为1的user,就会报空指针异常。
存在于jvm中,却不存在于数据库中的对象,适合以下情况:
1. 使用new关键字实例化出来的对象,还未保存到数据库中;
2. 从数据库中已经删除了的对象,还存在于jvm中时。(delete方法调用后)
存在于jvm中,也存在于数据库记录中,session未关闭,保持着对象与记录的同步,适合以下情况:
1. 将jvm中存在的对象保存或同步到数据库中记录后对象的状态。(save、update方法调用后)
注: session中有一个map存放着被托管的对象,也就是hibernate以及缓存对象的来源。
存在于jvm中,也存在于数据库记录中,session已关闭,对象与记录未保持同步,适合以下情况:
1. 对象已经持久化,session已关闭后的状态,不能保持对象与数据库记录的同步。(session的close、evict、clear方法被调用后)
当Session缓存中对象的属性每次发生了变化,Session并不会立即清理缓存和执行相关的SQL update语句,而是在特定的时间点才清理缓存,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,一遍减少访问数据库的次数,从而提高应用程序的数据访问性能。
在默认情况下,Session会在以下时间点清理缓存。
Transaction tx=session.beginTransaction();
User user=(User)session.load(User.class,”1”);//从数据库中加载符合条件的数据
user.setName(“zx”);//改变了user对象的姓名属性,此时user对象成为了所谓的“脏数据”
tx.commit();// 此时进行脏检查,将改变后的对象同步到数据库记录
当一个user对象被加入到Session缓存中时,Session会为user对象的值类型的属性复制一份快照。当Session清理缓存之前,会进行脏检查,即比较user对象的当前属性与它的快照,来判断user对象的属性是否发生了变化,如果发生了变化,就称这个对象是“脏对象”,Session会根据脏对象的最新属性来执行相关的update SQL语句,从而同步更新数据库。