【Java】Hibernate的检索策略
目录
Hibernate的检索策略
立即检索策略
延迟检索策略
左外连接检索策略
batch-size属性
①lazy有关的东西实验
②有关batch-size属性的实验,这个要提前用hql查询来做
③有关fetch东西实验
Hibernate的Session在加载一个Java对象时,可以将与这个对象相关联的其他Java对象都加载到缓存中,以便程序及时调用。但有些情况下,我们不需要加载太多无用的对象到缓存中,一来这样会撑爆内存,二来增加了访问数据库的次数。所以为了合理的使用缓存,Hibernate提供了几种检索策略来供用户选择。
Hibernate的检索策略
在Hibernate中主要有三种检索策略,它们是立即检索策略、延迟检索策略、左外连接检索策略。
下面分别介绍一下这三种检索策略。
立即检索策略
采用立即检索策略,会将被检索的对象,以及和这个对象关联的一对多对象都加载到缓存中。Session的get方法就使用的立即检索策略。
优点:频繁使用的关联对象能够被加载到缓存中。
缺点:1、占用内存。2、Select语句过多。
延迟检索策略
采用延迟检索策略,就不会加载关联对象的内容。直到第一次调用关联对象时,才去加载关联对象。在不涉及关联类操作时,延迟检索策略只适用于Session的load方法。涉及关联类操作时,延迟检索策略也能够适用于get,list等操作。
在类级别操作时(也就是只涉及一张表时), 延迟检索策略,只加载类的OID不加载类的其他属性,只用当第一次访问其他属性时,才会访问数据库去加载内容。
在关联级别操作时(也就是有一对多,多对多...关联关系时, 涉及多张表时),延迟检索策略,只加载类本身,不加载关联类,直到第一次调用关联对象时,才去加载关联对象
程序的默认模式都是用延迟加载策略。如果需要指定使用延迟加载策略。在配置文件中设置的lazy=true,的lazy=true或extra(增强延迟)的lazy=proxy和no-proxy。
优点:由程序决定加载哪些类和内容,避免了大量无用的sql语句和内存消耗。
缺点:在Session关闭后,就不能访问关联类对象了。强行访问就会发生赖加载异常, 所以需要确保在Session.close方法前,调用关联对象。
左外连接检索策略
采用左外连接检索,能够使用Sql的外连接查询,将需要加载的关联对象加载在缓存中。fetch设置为join,的fetch设置为 join
fetch除join取值外, 还有select和subselect的取值,它们决定了发起的sql语句的形式, 分开独立的select查询, 还是子查询, 还是外连接查询.
优点:1.对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便的从一个对象导航到与它关联的对象。2.使用了外连接,select语句数目少。
缺点:1.可能会加载应用程序不需要访问的对象,白白浪费许多内存空间。2.复杂的数据库表连接也会影响检索性能。
batch-size属性
无论是立即检索还是延迟检索,都可以指定关联查询的数量,这就需要使用batch-size属性来指定,指定关联查询数量,以减少批量检索的数据数目。从而提高检索的性能。
看例子:
①lazy有关的东西实验
在一个类的情况下,比较立即检索和延迟检索
标签上默认模式下:load方法,和load方法
什么时候用懒加载,什么时候不用: 如果程序加载一个对象的目的是为了访问它的某个属性, 就用立即加载, 如果加载对象是为了拿到它的应用, 就用延迟加载!
在类级别操作时(也就是只涉及一张表时), 延迟检索策略,只加载类的OID不加载类的其他属性,只用当第一次访问其他属性时,才会访问数据库去加载内容。
在关联级别操作时(也就是有一对多,多对多...关联关系时, 涉及多张表时),延迟检索策略,只加载类本身,不加载关联类,直到第一次调用关联对象时,才去加载关联对象, 这里主要说一下lazy=extra(增强延迟)表示,加载对象的时间,能延迟就尽可能的延迟,比lazy=true进一步的延迟。
比较发起的sql
即使lazy=true的时候, 也可以让延迟失效,Hibernate.initialize()这个静态方法
比较
②有关batch-size属性的实验,这个要提前用hql查询来做
没有batch-size, 有几个老师发起几条sql语句, 配置batch-size, 就会发起这个值整数倍的sql语句
③有关fetch东西实验
把in(?,?)语句变成了子查询!从原来的发起2条sql变成1条了! 这个时候, lazy有效, batch-size失效!
最后在看看,join取值, 这个例子改load一个对象时:
取值是join时,不能和batch-size属性一起用,加载一这端对象时,它会用左外连接将关联对象一起加载进来。而且这时lazy属性没有作用了。
注意:hql查询fetch=join是没有作用。