add( Restrictions.idEq(userId) ).uniqueResult();
(这就是其他ORM解决方案的“抓取计划(fetch plan)”在Hibernate中的等价物。)截然不同的一种避免N+1次查询的方法是,使用二级缓存。
示例配置(主要有两种情况):
1)单端关联(
可以给单端关联的映射元素添加fetch属性。fetch属性有两个可选值。
a).select:作为默认值,它的策略是党需要使用到关联关系对象的数据时,另外单独发送一条select语句抓取当前对象的关联对象的数据。即延时加载。
b).join:它的策略是在同一条select语句使用连接李艾获得对象的数据和它关联的对象的数据,此时关联对象的延迟加载失效.
以下是单端关联上fetch=join的一个配置示例
Java代码 收藏代码
< xml version="1.0" encoding="UTF-8" >
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
在应用程序中加载某个实体product的数据时,会使用内连接把它关联的Category实体也加载上来,即类似下面的SQL语句:
Sql代码 收藏代码
select tab1.xx,tab1.yy,tab2.aa,tab2.cc
from product tab1
inner join category tab2
on tab1.cate_id=tab2.id
where product_id=
2)集合属性上抓取策略
在集合属性的映射元素上可以添加fetch属性,他有三个可选值
a).select:作为默认值,它的策略是党需要使用所关联集合的数据时,另外单独发送一条select语句抓取当前对象的关联集合,即延时加载
b).join:在同一条select语句使用连接来获得对象的关联集合,此时关联集合上的lazy会失效
以下是集合属性上fetch=subselect的示例
Java代码 收藏代码
< xml version="1.0" encoding="UTF-8" >
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
当使用get()或load()方法加载一个Category实体数据时,它对关联的Product集合属性先延迟加载,当真正需要使用 Product集合属性中的数据时,才再发送一条SQL语句来抓取数据; 当使用HQL语句加载多个CategoryShiite数据时,对它们关联的Product集合属性先延迟加载,当真正需要使用Product集合属性的数据时,才会再发送一条子查询语句来抓取相应的数据
批量抓取:
(1)在Hibernate中,对于关联抓取,可以定义每次抓取数据的数量,批量地将数据载入内存,减少与数据库交互的次数。在应用程序中可以定义车间默认的关联抓取数量。在
(2)在映射定义文件中,可能在元素class中使用属性batch-size为持久化类指定批量抓取的数量。同样,如果要在集合中使用指定的批量,可以在集合元素set(list、bag等)中使用属性batch-size指定。如果同进采用了默认的批量抓取配置,又为持久化类或集合配置了特定的抓取数量,则类或集合的特定配置将覆盖配置文件中的默认批量抓取属性。
作者“ERDP技术架构”