1. Hibernate一级缓存
Hibernate的一级缓存就是指session缓存。
actionQueue它是一个行列队列,它主要记录crud操作的相关信息
persistenceContext它是持久化上下文,它其实是真正缓存。
在session中定义了一系列的集合来存储数据,它们构成session缓存。
只要session没有关闭,它就会一直存在。
当我们通过hibernate中的session提供的一些API例如 save get update等进行操作时,就会将持久化对象保存到session中,当下一次在去查询缓存中具有的对象(OID值来判断),
就不会去从数据库查询,而是直接从缓存中获取。
Hibernate的一级缓存存在的目的就是为了减少对数据库访问。
在hibernate中还有一个二级缓存,它是SessionFactory级别缓存。
1.1.一级缓存的存在
通过第八行断点,进行查看
1.2. 持久化对象具有自动更新数据库能力(快照更新)
// 测试一级缓存 @Test public void test3() { // 1.得到session Session session = HibernateUtils.openSession(); session.beginTransaction(); Customer c = session.get(Customer.class, 1); // 查询id=1的customer对象,如果查询到,会将c存储到一级缓存中。 Customer cc = session.get(Customer.class, 1); // 会从一级缓存 // 中查询,而不会向数据库在发送sql // 2.事务提供,关闭 session.getTransaction().commit(); session.close(); }
// 持久化对象具有自动更新数据库能力 @Test public void test4() { // 1.得到session Session session = HibernateUtils.openSession(); session.beginTransaction(); Customer c = session.get(Customer.class, 1); // 查询id=1的customer对象,如果查询到,会将c存储到一级缓存中。 c.setName("tom"); // 操作持久化对象来修改属性 // 2.事务提供,关闭 session.getTransaction().commit(); session.close(); }
为什么持久化对象具有自动更新数据库能力?
1.3. 一级缓存常用API
一级缓存特点:
当我们通过session的save,update saveOrupdate进行操作时,如果一级缓存中没有对象,会将这些对象从数据库中查询到,存储到一级缓存。
当我们通过session的load,get,Query的list等方法进行操作时,会先判断一级缓存中是否存在,如果没有才会从数据库获取,并且将查询的数据存储到一级缓存中。
当调用session的close方法时,session缓存清空。
clea()r 清空一级缓存.
evict(object) 清空一级缓存中指定的一个对象。
refresh()重新查询数据库,用数据库中信息来更新一级缓存与快照
close();关闭session时也会清空一级缓存
1.4. Hibernate常用API-Session补充
update
udpate操作它主要是针对于脱管对象,持久对象具有自动更新能力。
问题1:如果我们直接操作的对象是一个脱管对象,执行update会出现什么情况?
Update操作时,如果对象是一个脱管对象,可以操作,
它会将脱管对象转换成持久对象在操作
如果在session中出现相同的oid两个对象,会产生异常
问题2脱管对象的oid如果在数据表中不存在,会报异常?
所以:在操作中,建议我们通过持久化对象来直接修改其操作。
// 测试一级缓存操作常用API @Test public void test5() { // 1.得到session Session session = HibernateUtils.openSession(); session.beginTransaction(); // 操作 List<Customer> list = session.createQuery("from Customer").list(); // 会存储数据到一级缓存 session.clear(); // 清空一级缓存 Customer c = session.get(Customer.class, 1); // 会先从session一级缓存 // 中获取,如果不存在,才会从数据库获取 session.evict(c); // 从一级缓存 中删除一个指定的对象 Customer cc = session.get(Customer.class, 1); cc.setName("kkkk"); session.refresh(cc); // 重新查询数据库,用数据库中信息来更新一级缓存与快照 // 2.事务提供,关闭 session.getTransaction().commit(); session.close(); } // session的update操作 @Test public void test6() { // 1.得到session Session session = HibernateUtils.openSession(); session.beginTransaction(); //得到id=1的 Customer对象 //Customer cc=session.get(Customer.class, 1); //session一级缓存中存在了一个oid为1的Customer // 执行update来操作一个脱管对象 Customer c = new Customer(); c.setAddress("广州"); c.setName("赵六"); c.setId(11); session.update(c); //当执行update时会将c放入到session一级缓存 // 2.事务提供,关闭 session.getTransaction().commit(); session.close(); }
saveOrUpdate
如果对象是一个瞬时对象 --------执行save操作
如果对象是一个脱管对象---------执行update
如果是一个持久对象-------直接返回
delete
删除一个脱管对象,与session关联,在删除
注意:如果执行delete操作,先删除一级缓存,在删除数据库中的数据。
// session的update操作 @Test public void test6() { // 1.得到session Session session = HibernateUtils.openSession(); session.beginTransaction(); //得到id=1的 Customer对象 //Customer cc=session.get(Customer.class, 1); //session一级缓存中存在了一个oid为1的Customer // 执行update来操作一个脱管对象 Customer c = new Customer(); c.setAddress("广州"); c.setName("赵六"); c.setId(11); session.update(c); //当执行update时会将c放入到session一级缓存 // 2.事务提供,关闭 session.getTransaction().commit(); session.close(); }
saveOrUpdate
如果对象是一个瞬时对象 --------执行save操作
如果对象是一个脱管对象---------执行update
如果是一个持久对象-------直接返回
delete
删除一个脱管对象,与session关联,在删除
注意:如果执行delete操作,先删除一级缓存,在删除数据库中的数据。