标签:eve ade contains 不一致 属性 出现 name 创建 持久
首先Hibernate中的一级缓存默认是打开的,并且范围从session创建到session关闭,存储的数据必须是持久态的数据。
1 //从session创建开始,一级缓存也跟着创建 2 Session session = HibernateSessionFactory.getSession(); 3 ... 4 //到session关闭,一级缓存 5 session.close();
一级缓存的执行流程:
如果现在需要获得一个数据库里面的账号为“980517”的用户,执行Java代码
1 User user = (User)session.get(User.class,"980517")
这时底层并不是直接执行sql语句,而是先到缓存区去找,如果找不到账号为“980517”的用户,那么才会去执行sql语句,并把它放到缓存区中去,;如果在缓存区中找到了,就不会执行sql语句了(这就是优点:减少了操作数据库的次数),直接返回这个User对象。下面来粗略得看一看这部分的源码:
1 //数据加载一般都是在doLoad中完成,不仅仅是get()这个方法 2 protected final T doLoad(Serializable id) { 3 if ( this.lockOptions != null ) {//这个if就是去缓存区中去找,如果找到了,就带着数据直接return 4 LoadEvent event = new LoadEvent( id, entityPersister.getEntityName(), lockOptions, SessionImpl.this ); 5 fireLoad( event, LoadEventListener.GET ); 6 return (T) event.getResult(); 7 } 8 9 LoadEvent event = new LoadEvent( id, entityPersister.getEntityName(), false, SessionImpl.this ); 10 boolean success = false; 11 try { 12 fireLoad( event, LoadEventListener.GET ); 13 success = true; 14 } 15 catch (ObjectNotFoundException e) { 16 // if session cache contains proxy for non-existing object 17 } 18 finally { 19 afterOperation( success ); 20 } 21 return (T) event.getResult(); 22 }
一级缓存的特性:持久态可以直接更新数据库。
说这个特性之前提一个概念:快照区(副本,保留最开始的数据)
比如上面的User,它不仅会在一级缓存区存一份,也会在快照区存一份,当对User这个对象执行set方法来改变它的属性时,缓存区会跟着修改,但是快照区不会修改,这就会出现不一致的情况。当程序最后执行commit()方法提交事务的时候,它会比较缓存区和快照区,如果快照区的数据(也就是最开始的数据)和一级缓存区的数据不一致时,他就会执行一个更新的操作来更新数据库。这就意味着我们可以用先get后set的方式来取代hibernate中update更新数据库的方式。
如果理解有误还请斧正,感谢。
标签:eve ade contains 不一致 属性 出现 name 创建 持久
原文地址:https://www.cnblogs.com/baikaizhuliangshui/p/11785018.html