Hibernate的抓取策略

1.1 Hibernate的抓取策略
1.1.1 区分延迟和立即检索:
立即检索:
* 当执行某行代码的时候,马上发出SQL语句进行查询.
* get()
延迟检索:
* 当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句.
* load();
 
 
类级别检索和关联级别检索:
* 类级别的检索:
* <class>标签上配置lazy
* 关联级别的检索:
* <set>/<many-to-one>上面的lazy.
 
* 查询某个对象的时候,是否需要查询关联对象?
* 查询关联对象的时候是否采用延迟检索?
 
从一的一方关联多的一方:
* <set>
* fetch:控制sql语句的类型
* join :发送迫切左外连接的SQL查询关联对象.fetch=”join”那么lazy被忽略了.
* select :默认值,发送多条SQL查询关联对象.
* subselect :发送子查询查询关联对象.(需要使用Query接口测试)
 
* lazy:控制关联对象的检索是否采用延迟.
* true :默认值, 查询关联对象的时候使用延迟检索
* false :查询关联对象的时候不使用延迟检索.
* extra :极其懒惰.
 
***** 如果fetch是join的情况,lazy属性将会忽略 .
  *例如:
*①fecth="join"
Customer customer = (Customer) session.get(Customer.class, 1);
//其实就是发送一条SQL就把全部数据给查出来,一般默认值select是会发送多条SQL查询的
Hibernate:
select
customer0_.cid as cid0_1_,
customer0_.cname as cname0_1_,
orders1_.cid as cid0_3_,
orders1_.oid as oid3_,
orders1_.oid as oid1_0_,
orders1_.addr as addr1_0_,
orders1_.cid as cid1_0_
from
customer2 customer0_
left outer join
orders orders1_
on customer0_.cid=orders1_.cid
where
customer0_.cid=?

*②fecth="select" lazy="true"( <set>标签的默认值
Customer customer = (Customer) session.get(Customer.class, 1);
      System.out.println(customer.getOrders().size());
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid=?
//查询订单的数量时才发送这条SQL
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid=?


*③fecth="select" lazy="false" (关联对象的检索不使用延迟)
Customer customer = (Customer) session.get(Customer.class, 1);
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid=?
//不需要用到订单就直接先发送SQL查询
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid=?


*④fecth="select" lazy="extra" (极其懒惰)
    Customer customer = (Customer) session.get(Customer.class, 1);
    System.out.println(customer.getOrders().size());
    for(Order order : customer.getOrders()) {
    System.out.println(order);
    }
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid=?
//查数数量的SQL
Hibernate:
select
count(oid)
from
orders
where
cid =?
//列出订单详细再发送查询订单详细的SQL
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid=?


*⑤fecth="subselect" lazy="true" (需要使用Query接口测试)
*查询一个客户和查询多个客户
where cno=1 he where cno in(1,2,3)
总结:所以查询多个客户subselect才有效果
查询一个客户:
List<Customer> list = session.createQuery("from Customer c where cid =1").list();
for(Customer customer : list) {
System.out.println(customer);
}
Hibernate:
select
customer0_.cid as cid0_,
customer0_.cname as cname0_
from
customer2 customer0_
where
customer0_.cid=1
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid=?
查询多个客户:
List<Customer> list = session.createQuery("from Customer c where cid in(1,2)").list();
for(Customer customer : list) {
System.out.println(customer);
}
Hibernate:
select
customer0_.cid as cid0_,
customer0_.cname as cname0_
from
customer2 customer0_
where
customer0_.cid in (
1 , 2
)
//查询相关订单信息时用到子查询
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid in (
select
customer0_.cid
from
customer2 customer0_
where
customer0_.cid in (
1 , 2
)
)

在多的一方关联一的一方:
* <many-to-one>
* fetch:控制SQL语句发送格式
* join :发送一个迫切左外连接查询关联对象.fetch=”join”,lay属性会被忽略.
* select :发送多条SQL检索关联对象.
* lazy:关联对象检索的时候,是否采用延迟
* false :不延迟
* proxy :使用代理.检索订单额时候,是否马上检索客户 由Customer对象的映射文件中<class>上lazy属性来决定.
* no-proxy :不使用代理
例子(测试的时候一的一方没配置抓取策略):
*①没有配置
 Order order = (Order) session.get(Order.class, 19);
       System.out.println(order.getCustomer().getCname());
//查询订单SQL
Hibernate:
select
order0_.oid as oid1_0_,
order0_.addr as addr1_0_,
order0_.cid as cid1_0_
from
orders order0_
where
order0_.oid=?
//查询关联的客户再发送SQL
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid=?


*②fetch="join" lazy被忽略
Order order = (Order) session.get(Order.class, 19);
System.out.println(order.getCustomer().getCname());
//只发送一条迫切左外链接的SQL
Hibernate:
select
order0_.oid as oid1_1_,
order0_.addr as addr1_1_,
order0_.cid as cid1_1_,
customer1_.cid as cid0_0_,
customer1_.cname as cname0_0_
from
orders order0_
left outer join
customer2 customer1_
on order0_.cid=customer1_.cid
where
order0_.oid=?

*③fetch="select" lazy="false"
Order order = (Order) session.get(Order.class, 19);
System.out.println(order.getCustomer().getCname());
//再查询order的时候就直接发送多一条SQL关联上客户信息
Hibernate:
select
order0_.oid as oid1_0_,
order0_.addr as addr1_0_,
order0_.cid as cid1_0_
from
orders order0_
where
order0_.oid=?
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid=?


*③fetch="select" lazy="proxy"
*由一的一方的<class>标签上的lazy的属性值决定

批量抓取:( 都是在一的一端去配置
1、*在Customer的<set>标签上设置batch-size属性
测试的时候,list中一共有5个customer,
Session session = HibernateUtils.openSessioin();
Transaction tx = session.beginTransaction();
List<Customer> list = session.createQuery("from Customer").list();
for(Customer customer : list) {
for(Order order : customer.getOrders()) {
System.out.println(order.getAddr());
}
}
如果 batch-size=''2'' ,查询订单时会发送3次SQL查询 (2,2,1)
Hibernate:
select
customer0_.cid as cid0_,
customer0_.cname as cname0_
from
customer2 customer0_
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid in (
?, ?
)

Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid in (
?, ?
)

Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid= ?


如果 batch-size=''3'' ,查询订单时会发送2次SQL查询 (3,2)
Hibernate:
select
customer0_.cid as cid0_,
customer0_.cname as cname0_
from
customer2 customer0_
//先批量抓取了三个客户的订单信息
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid in (
?, ?, ?
)

//再批量抓取剩下的两个客户的订单信息
Hibernate:
select
orders0_.cid as cid0_1_,
orders0_.oid as oid1_,
orders0_.oid as oid1_0_,
orders0_.addr as addr1_0_,
orders0_.cid as cid1_0_
from
orders orders0_
where
orders0_.cid in (
?, ?
)


2、*在Order的<many-to-one>标签上设置batch-size属性
一共有10个订单,每两个订单对应一个客户,就是每个客户有两个订单,一共有5个客户。注意:测试的时候将Customer的<set>便签的lazy等于true,Order的<many-to-one>标签的lazy等于true,方便测试。
Session session = HibernateUtils.openSessioin();
Transaction tx = session.beginTransaction();
List<Order> list = session.createQuery("from Order").list();
for(Order order : list) {
System.out.println(order.getCustomer().getCname());
}

如果 batch-size=''2'' ,查询订单时会发送3次SQL查询 (2,2,1)
Hibernate:
select
order0_.oid as oid1_,
order0_.addr as addr1_,
order0_.cid as cid1_
from
orders order0_
//先批量抓取两个客户
Hibernate:
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid in (
?, ?
)

//再批量抓取两个客户
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid in (
?, ?
)

//抓取一个客户
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid= ?

如果 batch-size=''3'' ,查询订单时会发送2次SQL查询 (3,2)
Hibernate:
select
order0_.oid as oid1_,
order0_.addr as addr1_,
order0_.cid as cid1_
from
orders order0_
//先批量抓取三个客户
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid in (
?, ?, ?
)

//再批量抓取两个客户
Hibernate:
select
customer0_.cid as cid0_0_,
customer0_.cname as cname0_0_
from
customer2 customer0_
where
customer0_.cid in (
?, ?
)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值