检索策略
类级别检索
默认检索策略:默认延迟加载, 可以使用lazy属性来进行改变.
session.get(clazz,object)默认立即加载
@Test //测试左外连接查询
public void test13(){
Session session = HibernateUtils.getSession();
Transaction bt = session.beginTransaction();
Customer customer = session.get(Customer.class,1);
bt.commit();
session.close();
}
session.load(clazz,object)默认延迟加载 可以使用Hibernate.initialize(customer)初始化数据;
@Test //load延迟加载
public void test14(){
Session session = HibernateUtils.getSession();
Transaction bt = session.beginTransaction();
Customer customer = session.load(Customer.class,1);
bt.commit();
session.close();
}
关联级别检索
一对一<one-to-one>
一对多/多对一 <set>下有<one-to-many> <many-to-one>
多对多<many-to-many>
我们主要是在set下one-to-many或many-to-one设置lazy和fetch
查询一个客户下的订单
set上
| lazy |
|
||||||
| fetch |
|
未进行设置则默认为懒加载
@Test
public void test15(){
Session session = HibernateUtils.getSession();
Transaction bt = session.beginTransaction();
String hql="from Customer c right outer join c.orders";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
bt.commit();
session.close();
}
sql打印:
Hibernate:
select
customer0_.c_id as c_id1_0_,
customer0_.name as name2_0_
from
test.c_customer customer0_
打印结果证明只进行查询了customer对象
其中Order对象未进行加载 这样就是在调用时会发送sql语句进行查询 为了解决这一事件 我们让Customer立即加载
修改其配置文件:
<set lazy="false" > //设置立即加载
再次执行会sql打印
Hibernate:
select
customer0_.c_id as c_id1_0_,
customer0_.name as name2_0_
from
test.c_customer customer0_
Hibernate:
select
orders0_.o_customer_id as o_custom4_1_0_,
orders0_.o_id as o_id1_1_0_,
orders0_.o_id as o_id1_1_1_,
orders0_.o_money as o_money2_1_1_,
orders0_.o_receiverInfo as o_receiv3_1_1_,
orders0_.o_customer_id as o_custom4_1_1_
from
test.o_order orders0_
where
orders0_.o_customer_id=?
Hibernate:
select
orders0_.o_customer_id as o_custom4_1_0_,
orders0_.o_id as o_id1_1_0_,
orders0_.o_id as o_id1_1_1_,
orders0_.o_money as o_money2_1_1_,
orders0_.o_receiverInfo as o_receiv3_1_1_,
orders0_.o_customer_id as o_custom4_1_1_
from
test.o_order orders0_
where
orders0_.o_customer_id=?
这样在查询customer时会进行查询order
测试lazy=extra属性
<set lazy="true" > //设置延迟加载
执行以下方法
@Test
public void test15(){
Session session = HibernateUtils.getSession();
Transaction bt = session.beginTransaction();
String hql="from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
/*int size = list.size();
System.out.println(size);*/
for (Customer customer : list) {
System.out.println(customer.getOrders().size());
}
//操作
bt.commit();
session.close();
}
sql打印:
Hibernate:
select
customer0_.c_id as c_id1_0_,
customer0_.name as name2_0_
from
test.c_customer customer0_
Hibernate:
select
orders0_.o_customer_id as o_custom4_1_0_,
orders0_.o_id as o_id1_1_0_,
orders0_.o_id as o_id1_1_1_,
orders0_.o_money as o_money2_1_1_,
orders0_.o_receiverInfo as o_receiv3_1_1_,
orders0_.o_customer_id as o_custom4_1_1_
from
test.o_order orders0_
where
orders0_.o_customer_id=?
1
Hibernate:
select
orders0_.o_customer_id as o_custom4_1_0_,
orders0_.o_id as o_id1_1_0_,
orders0_.o_id as o_id1_1_1_,
orders0_.o_money as o_money2_1_1_,
orders0_.o_receiverInfo as o_receiv3_1_1_,
orders0_.o_customer_id as o_custom4_1_1_
from
test.o_order orders0_
where
orders0_.o_customer_id=?
100
<set lazy="extra" > //设置加强延迟加载
sql打印为:
Hibernate:
select
customer0_.c_id as c_id1_0_,
customer0_.name as name2_0_
from
test.c_customer customer0_
Hibernate:
select
count(o_id)
from
test.o_order
where
o_customer_id =?
1
Hibernate:
select
count(o_id)
from
test.o_order
where
o_customer_id =?
100
总结:
对于懒加载和加强懒加载区别:都是是在调用时才会产生,但是区别在于发送sql语句的意义;
懒加载在发送sql语句时会发送查询全部的语句,返回为每一列,而加强懒加载发送的是count(*),我需要什么加强懒加载会给我什么直接查询,而懒加载不会.
测试fetch 只是sql的生成方式不同而已
<set name="orders" lazy="false" fetch="subselect" > //subselect生成子查询
@Test
public void test15(){
Session session = HibernateUtils.getSession();
Transaction bt = session.beginTransaction();
String hql="from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
bt.commit();
session.close();
}
sql打印:
Hibernate:
select
customer0_.c_id as c_id1_0_,
customer0_.name as name2_0_
from
test.c_customer customer0_
Hibernate:
select
orders0_.o_customer_id as o_custom4_1_1_,
orders0_.o_id as o_id1_1_1_,
orders0_.o_id as o_id1_1_0_,
orders0_.o_money as o_money2_1_0_,
orders0_.o_receiverInfo as o_receiv3_1_0_,
orders0_.o_customer_id as o_custom4_1_0_
from
test.o_order orders0_
where
orders0_.o_customer_id in ( //子查询
select
customer0_.c_id
from
test.c_customer customer0_
)
在<many-to-one>或<one-to-one>如果去查询对方
| fetch |
|
||||||
| lazy |
|