您的位置:首页 > 其它

Hibernate的检索策略

2011-12-25 18:09 357 查看
一, Hibernate的检索策略包括类级别检索策略和关联级别检索策略。Hibernate的检索策略包括类级别检索策略和关联级别检索策略。

二, 类级别检索策略有立即检索和延迟检索,默认的检索策略是立即检索。

三, 立即检索

在映射文件中设置<hibernate-mapping
package="cn.csdn.producets.domain" default-lazy="false">

<classname="Customers" table="Customers" lazy=”false”>

<setname="orders" lazy="false">

四, 延迟检索

设置lazy=”false”不采用延迟检索

<set name="orders" lazy=”false”>

Customers c=(Customers) session.get(Customers.class, 2);
System.out.println(c.getEmail());

运行结果:Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_, customers0_.passas pass0_0_, customers0_.sex as sex0_0_, customers0_.petName as petName0_0_,customers0_.email as email0_0_, customers0_.rdate as rdate0_0_
from Customerscustomers0_ where customers0_.id=?
Hibernate: select orders0_.cid as cid0_1_,orders0_.id as id1_, orders0_.id as id1_0_, orders0_.number as number1_0_,orders0_.address as address1_0_, orders0_.phone as phone1_0_, orders0_.odate asodate1_0_, orders0_.sum as sum1_0_, orders0_.status
as status1_0_, orders0_.cidas cid1_0_ from orders orders0_ where orders0_.cid=?

设置lazy=”true”采用延迟加载

<set name="orders" lazy=”false”>

Customers c=(Customers) session.get(Customers.class, 2);
System.out.println(c.getEmail());

运行结果:Hibernate: select customers0_.id as id0_0_,customers0_.realName as realName0_0_, customers0_.pass as pass0_0_,customers0_.sex as sex0_0_, customers0_.petName as petName0_0_,customers0_.email as email0_0_, customers0_.rdate as rdate0_0_ from Customerscustomers0_
where customers0_.id=?

总结:采用懒加载是会少输出一条sql查询语句;

五,关联级别检索策略有立即检索、延迟检索和迫切左外连接检索。

Fech=”join”;

第一种测试方式:<set name="orders" fetch="join" lazy=”true”>

Customers c=(Customers) session.get(Customers.class, 2);
System.out.println(c.getEmail());

代码执行结果:

Hibernate: select customers0_.id as id0_1_,customers0_.realName as realName0_1_, customers0_.pass as pass0_1_,customers0_.sex as sex0_1_, customers0_.petName as petName0_1_,customers0_.email as email0_1_, customers0_.rdate as rdate0_1_, orders1_.cid ascid0_3_,
orders1_.id as id3_, orders1_.id as id1_0_, orders1_.number asnumber1_0_, orders1_.address as address1_0_, orders1_.phone as phone1_0_,orders1_.odate as odate1_0_, orders1_.sum as sum1_0_, orders1_.status asstatus1_0_, orders1_.cid as cid1_0_ from Customers
customers0_ left outer joinorders orders1_ on customers0_.id=orders1_.cid where customers0_.id=?

可以从运行结果中得知:采用迫切左外链接

第二种测试方式:<set name="orders" fetch="join" lazy=”false”>

Customers c=(Customers) session.get(Customers.class, 2);
System.out.println(c.getEmail());

代码执行结果:

Hibernate: select customers0_.id as id0_1_, customers0_.realNameas realName0_1_, customers0_.pass as pass0_1_, customers0_.sex as sex0_1_,customers0_.petName as petName0_1_, customers0_.email as email0_1_,customers0_.rdate as rdate0_1_, orders1_.cid as cid0_3_,
orders1_.id as id3_,orders1_.id as id1_0_, orders1_.number as number1_0_, orders1_.address asaddress1_0_, orders1_.phone as phone1_0_, orders1_.odate as odate1_0_,orders1_.sum as sum1_0_, orders1_.status as status1_0_, orders1_.cid as cid1_0_from Customers
customers0_ left outer join orders orders1_ oncustomers0_.id=orders1_.cid where customers0_.id=?

可以从运行结果中得知:采用迫切左外链接

第三种测试方式:<set name="orders" fetch="join" lazy=”extra”>

Customers c=(Customers) session.get(Customers.class, 2);
System.out.println(c.getEmail());

代码执行结果:

Hibernate: select customers0_.id as id0_1_,customers0_.realName as realName0_1_, customers0_.pass as pass0_1_,customers0_.sex as sex0_1_, customers0_.petName as petName0_1_,customers0_.email as email0_1_, customers0_.rdate as rdate0_1_, orders1_.cid ascid0_3_,
orders1_.id as id3_, orders1_.id as id1_0_, orders1_.number asnumber1_0_, orders1_.address as address1_0_, orders1_.phone as phone1_0_,orders1_.odate as odate1_0_, orders1_.sum as sum1_0_, orders1_.status asstatus1_0_, orders1_.cid as cid1_0_ from Customers
customers0_ left outer joinorders orders1_ on customers0_.id=orders1_.cid where customers0_.id=?

可以从运行结果中得知:采用迫切左外链接

总结:若把fech属性设置为join则lazy属性就不起作用

二.Fech=”select”

第一种测试方式:<set name="orders" fetch="select" lazy=”true”>

Customersc=(Customers) session.get(Customers.class, 2);
System.out.println(c.getEmail());
System.out.println(c.getOrders().size());

运行结果:Hibernate: select customers0_.id as id0_0_, customers0_.realName asrealName0_0_, customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from
Customers customers0_ where customers0_.id=?
null
Hibernate:select orders0_.cid as cid0_1_, orders0_.id as id1_, orders0_.id as id1_0_,orders0_.number as number1_0_, orders0_.address as address1_0_, orders0_.phoneas phone1_0_, orders0_.odate as odate1_0_, orders0_.sum as sum1_0_,orders0_.status
as status1_0_, orders0_.cid as cid1_0_ from orders orders0_where orders0_.cid=?
1结论:采用延迟加载;

第二种测试方式:<set name="orders" fetch="select" lazy=”false”>

Customers c=(Customers) session.get(Customers.class, 2);

运行结果:Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from
Customers customers0_ where customers0_.id=?
Hibernate:select orders0_.cid as cid0_1_, orders0_.id as id1_, orders0_.id as id1_0_,orders0_.number as number1_0_, orders0_.address as address1_0_, orders0_.phoneas phone1_0_, orders0_.odate as odate1_0_, orders0_.sum as sum1_0_,orders0_.status
as status1_0_, orders0_.cid as cid1_0_ from orders orders0_where orders0_.cid=?
结论:采用立即检索

第三种测试方式:<setname="orders" fetch="select"lazy=”extra”>

Customersc=(Customers) session.get(Customers.class, 2);
System.out.println(c.getEmail());
System.out.println(c.getOrders().size());
运行结果:Hibernate: selectcustomers0_.id as id0_0_, customers0_.realName as realName0_0_,customers0_.pass as pass0_0_, customers0_.sex as sex0_0_, customers0_.petNameas petName0_0_, customers0_.email as email0_0_, customers0_.rdate as rdate0_0_from
Customers customers0_ where customers0_.id=?
null
Hibernate:select count(id) from orders where cid =?
1
结论:采用延迟加载
总结:听从lazy属性的

三.Fech=”subselect”;

第一种测试方式:<setname="orders" fetch="subselect"lazy=”true”>

Customers c=(Customers)session.get(Customers.class, 2);
System.out.println(c.getEmail());
System.out.println(c.getOrders().size());
Set<Orders>orders=c.getOrders();
for(Orders o:orders){
System.out.println(o.getNumber());
}
session.close();
}

运行结果:Hibernate: select customers0_.id as id0_0_, customers0_.realName asrealName0_0_, customers0_.pass as pass0_0_, customers0_.sex as sex0_0_,customers0_.petName as petName0_0_, customers0_.email as email0_0_,customers0_.rdate as rdate0_0_
from Customers customers0_ wherecustomers0_.id=?
null
Hibernate: select orders0_.cid as cid0_1_,orders0_.id as id1_, orders0_.id as id1_0_, orders0_.number as number1_0_,orders0_.address as address1_0_, orders0_.phone as phone1_0_, orders0_.odate asodate1_0_, orders0_.sum as sum1_0_, orders0_.status
as status1_0_, orders0_.cidas cid1_0_ from orders orders0_ where orders0_.cid=?
1
2

结论:采用延迟加载;

第二种测试方式:<setname="orders" fetch="subselect"lazy=”false”>

Customers c=(Customers)session.get(Customers.class, 2);
System.out.println(c.getEmail());
System.out.println(c.getOrders().size());
Set<Orders>orders=c.getOrders();
for(Orders o:orders){
System.out.println(o.getNumber());
}
session.close();
}

运行结果:Hibernate: select customers0_.id as id0_0_, customers0_.realName asrealName0_0_, customers0_.pass as pass0_0_, customers0_.sex as sex0_0_,customers0_.petName as petName0_0_, customers0_.email as email0_0_,customers0_.rdate as rdate0_0_
from Customers customers0_ wherecustomers0_.id=?
Hibernate: select orders0_.cid as cid0_1_,orders0_.id as id1_, orders0_.id as id1_0_, orders0_.number as number1_0_,orders0_.address as address1_0_, orders0_.phone as phone1_0_, orders0_.odate asodate1_0_, orders0_.sum as sum1_0_, orders0_.status
as status1_0_, orders0_.cidas cid1_0_ from orders orders0_ where orders0_.cid=?
null
1
2
结论:采用立即检索

第三种测试方式:<setname="orders" fetch="subselect"lazy=”extra”>

Customers c=(Customers)session.get(Customers.class, 2);
System.out.println(c.getEmail());
System.out.println(c.getOrders().size());
Set<Orders>orders=c.getOrders();
for(Orders o:orders){
System.out.println(o.getNumber());
}
session.close();
}

运行结果:Hibernate: select customers0_.id as id0_0_, customers0_.realName asrealName0_0_, customers0_.pass as pass0_0_, customers0_.sex as sex0_0_,customers0_.petName as petName0_0_, customers0_.email as email0_0_,customers0_.rdate as rdate0_0_
from Customers customers0_ wherecustomers0_.id=?
null
Hibernate: select count(id) from orders wherecid =?
1
Hibernate: select orders0_.cid as cid0_1_,orders0_.id as id1_, orders0_.id as id1_0_, orders0_.number as number1_0_,orders0_.address as address1_0_, orders0_.phone as phone1_0_, orders0_.odate asodate1_0_, orders0_.sum as sum1_0_, orders0_.status
as status1_0_, orders0_.cidas cid1_0_ from orders orders0_ where orders0_.cid=?
2

结论:采用延迟检索

总结; Lazy属性决定检索策略

对于检索策略,需要根据实际情况进行选择。对于立即检索和延迟检索,它们的优点在于select语句简单(每张表一条语句)、查询速度快,缺点在于关联表时需要多条select语句,增加了访问数据库的频率。因此在选择即检索和延迟检索时,可以考虑使用批量检索策略来减少select语句的数量(配置batch-size属性)。对于切左外连接检索,优点在于select较少,但缺点是select语句的复杂度提高,多表之间的关联会是很耗时的操作。另外,配置文件是死的,但程序是活的,可以根据需要在程序里显示的指定检索策略(可能经常需要在程序中显示指定迫切左外连接检索)。为了清楚检索策略的配置效果如何,可以配置show_sql属性查看程序运行时Hibernate执行的sql语句。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: