Hibernate中延迟加载和缓存(4)

看到结果后你可能会大吃一惊,我没配集合缓存时他只生成一条sql语句我陪完之后怎么变成两条sql了?但是你注意看着两条sql语句是一模一样的,都是根据员工对象的OID来进行查询的!那么员工对象的OID是从哪来的呢?没错,就是从二级缓存中获取的至于为什么只是缓存员工对象的OID而没有缓存其他属性值,是因为员工对象没有配置二级缓存其不能进入二级缓存也就没有办法从二级缓存中拿到它的其他属性值,我们对员工对象配置二级缓存后再来进行测试。

其结果如下:

wpsCEB3.tmp

查询缓存 查询缓存的配置

在hibernate.cfg.xml配置文件中加入上述元素开启二级缓存。并且在使用Query进行缓存时必须在获取集合前调用query1.setCacheable(true);

下面编写测试用例进行测试:

wpsCEB5.tmp

测试结果:

wpsCEB6.tmp

注意:

1.查询缓存是基于二级缓存的在配置查询缓存时必须配置二级缓存否则将抛出如下异常

wpsCEB7.tmp

2.在查询缓存中保存的是对象内存地址的引用而不是对象的散装属性。

3.查询缓存是根据两次HQL查询语句经Hibernate内部转化后生成的sql语句是否一样留在决定是否和数据库进行交互而不是根据其对象的OID如下面的测试用例虽然查询的是OID相同的对象但还是会和数据库进行交互!

wpsCEB8.tmp

测试结果:

wpsCEB9.tmp

延迟加载和缓存遗留问题 Lazy属性和fetch属性连用

在一对多或者多对多检索策略由lazy和fetch共同确定,Lazy:决定关联对象初始化时机,Fetch:决定SQL语句构建形式。Fetch属性的取值为:Join:迫切左外连接、Select:多条简单SQL(默认值)、Subselect:子查询。当Fetch属性取值为join是将忽略lazy属性采用立即加载策略。例如插叙编号为5的部门,即便将部门映射文件中映射员工集合的set元素中的lazy属性设置为true或extra其还是会立即加载出该部门下的所有员工的集合,其Hibernate内部生成的sql语句如下:

wpsCEBA.tmp

Query接口的list方法和iterate方法的区别

1.返回的类型不一样,list返回List,iterate返回Iterator,
2.获取数据的方式不一样,list会直接查数据库,iterate会先到数据库中把id都取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1。
3.iterate会查询2级缓存,list 只会缓存,但不会使用缓存(除非结合查询缓存)。
4.list中返回的List中每个对象都是原本的对象,iterate中返回的对象是代理对象

缓存的内部存储实现

1.在缓存中都是以map集合的形式对象数据

2.一级缓存和二级缓存中都是以对象的OID作为map结合的key值而查询缓存是以Hibernate内部生成的sql语句作为key值

3.一级缓存和查询缓存中map集合的value值存放的是内存对象的引用,而二级缓存中存放的是对象的散装属性。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/6920e766361750004bdd71cc56ddc4ff.html