您的位置:首页 > 编程语言 > Java开发

JavaEE--SSH--hibernate-对象标识符,一级缓存,快照机制

2018-03-05 12:31 267 查看
hibernate 对象标识符(OID),对象状态,一级缓存以及快照机制:
一.首先介绍一下OID(对象标识符)
什么是OID:
OID是关系数据库中主键在Java对象模型中的等价物.Hibernate根据OID来维持Java对象和数据库中的对应关系。OID可以确保对象的唯一性.
也就是说hibernate内部有一个属性专门区分不同对象的主键属性值是否相同.如果相同则代表这个对象不是唯一的,就会报错.
代码测试:
public void test03(){
//测试Hibernate如何区分不同的对象
//将LinkMan.hbm.xml中id标签内的generator手动设置
//<generator class="assigned"></generator>
//修改Hibernate.cfg.xml中的配置
//<property name="hibernate.hbm2ddl.auto">create</property>
LinkMan m1=new LinkMan();
LinkMan m2=new LinkMan();
m1.setLkmId(new Long(1));
m2.setLkmId(new Long(2));//如果ID值都是1,报错
// A different object with the same identifier value was already associated with the session :
m1.setLkmName("tom");
m2.setLkmName("tom");
Session sess = HibernateUtil.getOpenSession();
Transaction tx = sess.beginTransaction();
sess.save(m1);
sess.save(m2);
tx.commit();
sess.close();

}
二.对象的状态:
hibernate为了方便管理持久化对象,将对象分为三种状态.
瞬时态,持久态和脱管态(游离态)
瞬时态:刚创建好的Java对象,其上没有生成对象标识符(OID),也没有纳入session管理.数据库中没有与之对应的数据.
持久态:有对象标识符.纳入session管理数据库中可能有与之对应的数据,也可能没有.
脱管态:有对象标识符,session已经失去了对它的管理.
三种状态如何转换:
瞬时态->持久态 save update
瞬时态->托管态 setId() //设置对象标识符(OID),而且必须是数据库中存在的
持久态->瞬时态 delete
持久态->脱管态 close
脱管态->瞬时态 将id设置为null 
脱管态->持久态 update,save



三.那什么是一级缓存呢:
先说说缓存:缓存就是把系统中经常访问的数据,从数据库中获取到放到缓存中.减少与数据库的访问次数,优点是减轻了数据库的压力,提高了性能.
而hibernate也提供了这样的缓存,分为一级缓存,二级缓存(不常用不说了).
一级缓存是session级别的缓存.只要session存在,session的数据也会存在.而所有的持久态对象都会保存在一级缓存当中.
一级缓存的存在感:
当我们第一次从数据库中get/load时,会发送SQL从数据库进行查询.
          第二次get/load时(同一OID对象),会直接从缓存中读取数据.不会发送SQL.
一级缓存的特点:
1.当调用session的save(),update(),saveOrUpdate()时,如果session缓存中没有相应对象,会自动查询并放入一级缓存中.
2.当调用session的load()/get(),以及query的list(),iterator()时,如果如果session缓存中没有相应对象,会自动查询并放入一级缓存中.
3.当调用session的close方法后,session的缓存会被清空.

这里顺便提一下get()和load()的区别
1.发出sql语句时机不同:
get()是立即发出sql
load()是延迟加载.只有用到加载的数据时才发送sql
2.返回的结果不一样.
get() 返回实际的对象
load() 返回代理对象
四.一级缓存下的快照机制:
快照其实是数据在内存中的副本,是数据库的数据在内存中的映射.
快照的作用是跟数据库数据保持一致,
原理:
当我们第一次查询的时候,查到的数据会保存两份,一份给一级缓存,一份给快照.
当我们对数据进行修改后(实际是修改一级缓存中的实体类对象),执行flush()或commit()时,hibernate会比较一级缓存的数据和快照的数据是否相同,如果不同,会将一级缓存的数据用sql形式发到数据库,并且同步快照.
快照的作用:
利用快照技术进行更新,不需要手动调用update方法,当我们commit()/flush()时会自动发出update语句.来确保数据库-一级缓存-快照三者数据的一致性.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: