1. 查询策略:使用Hibernate查询一个对象的时候,查询其关联对象.应该如何查询。是Hibernate的一种优化手段!
2. Hibernate框架的检索策略解决的问题
* 查询的时机
Customer c1 = (Customer) session.get(Customer.class, 1);
System.out.println(c1.getLinkmans().size());
* lazy属性解决查询的时机的问题,需要配置是否采用延迟加载!
* 查询的语句形式
List<Customer> list = session.createQuery("from Customer").list();
for(Customer c : list){
System.out.println(c.getLinkmans());
}
* join 连接查询.发送的是一条迫切左外连接!!!配置了join.lazy就失效了
* subselect 子查询。发送一条子查询查询其关联对象(需要使用list()方法进行测试)。
false 不延迟
extra 极其懒惰
2. Hibernate框架的检索策略解决的问题
* 查询的时机
Customer c1 = (Customer) session.get(Customer.class, 1);
System.out.println(c1.getLinkmans().size());
* lazy属性解决查询的时机的问题,需要配置是否采用延迟加载!
* 查询的语句形式
List<Customer> list = session.createQuery("from Customer").list();
for(Customer c : list){
System.out.println(c.getLinkmans());
}
* fetch属性就可以解决查询语句的形式的问题!
一、fetch能做什么?
先看一个例子:
@Test
public void run4() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
List<Customer> list = session.createQuery(" from Customer ").list();
for (Customer customer : list) {
System.out.println(customer.getLinkmans().size());
}
tx.commit();
}
上面方法执行之后,得到的日志:
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Hibernate:
select
customer0_.cust_id as cust_id1_0_,
customer0_.cust_name as cust_nam2_0_,
customer0_.cust_user_id as cust_use3_0_,
customer0_.cust_create_id as cust_cre4_0_,
customer0_.cust_source as cust_sou5_0_,
customer0_.cust_industry as cust_ind6_0_,
customer0_.cust_level as cust_lev7_0_,
customer0_.cust_linkman as cust_lin8_0_,
customer0_.cust_phone as cust_pho9_0_,
customer0_.cust_mobile as cust_mo10_0_
from
cst_customer customer0_
Hibernate:
select
linkmans0_.lkm_cust_id as lkm_cus10_1_0_,
linkmans0_.lkm_id as lkm_id1_1_0_,
linkmans0_.lkm_id as lkm_id1_1_1_,
linkmans0_.lkm_name as lkm_name2_1_1_,
linkmans0_.lkm_gender as lkm_gend3_1_1_,
linkmans0_.lkm_phone as lkm_phon4_1_1_,
linkmans0_.lkm_mobile as lkm_mobi5_1_1_,
linkmans0_.lkm_email as lkm_emai6_1_1_,
linkmans0_.lkm_qq as lkm_qq7_1_1_,
linkmans0_.lkm_position as lkm_posi8_1_1_,
linkmans0_.lkm_memo as lkm_memo9_1_1_,
linkmans0_.lkm_cust_id as lkm_cus10_1_1_
from
cst_linkman linkmans0_
where
linkmans0_.lkm_cust_id=?
3
Hibernate:
select
linkmans0_.lkm_cust_id as lkm_cus10_1_0_,
linkmans0_.lkm_id as lkm_id1_1_0_,
linkmans0_.lkm_id as lkm_id1_1_1_,
linkmans0_.lkm_name as lkm_name2_1_1_,
linkmans0_.lkm_gender as lkm_gend3_1_1_,
linkmans0_.lkm_phone as lkm_phon4_1_1_,
linkmans0_.lkm_mobile as lkm_mobi5_1_1_,
linkmans0_.lkm_email as lkm_emai6_1_1_,
linkmans0_.lkm_qq as lkm_qq7_1_1_,
linkmans0_.lkm_position as lkm_posi8_1_1_,
linkmans0_.lkm_memo as lkm_memo9_1_1_,
linkmans0_.lkm_cust_id as lkm_cus10_1_1_
from
cst_linkman linkmans0_
where
linkmans0_.lkm_cust_id=?
2
产生了3条sql。fetch决定sql的格式。fetch和lazy配置使用。
二、在set标签上配置策略
三、在many-to-one标签上配置策略
在<set>标签上使用fetch和lazy属性
fetch的取值 控制SQL语句生成的格式
* select 默认值.发送查询语句* join 连接查询.发送的是一条迫切左外连接!!!配置了join.lazy就失效了
* subselect 子查询。发送一条子查询查询其关联对象(需要使用list()方法进行测试)。
lazy的取值 查找关联对象的时候是否采用延迟!
true 默认.延迟false 不延迟
extra 极其懒惰
set标签上的默认值是fetch="select"和lazy="true"
3.1 fetch="select"&lazy="true"
/**
* 默认值是:fetch="select" lazy="true"
*/
@Test
public void run1() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//先查询1号客户
Customer c1 = session.get(Customer.class, 1L);
//看客户下所有的联系人
System.out.println(c1.getLinkmans().size());
tx.commit();
}
看日志:
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Hibernate:
select
customer0_.cust_id as cust_id1_0_0_,
customer0_.cust_name as cust_nam2_0_0_,
customer0_.cust_user_id as cust_use3_0_0_,
customer0_.cust_create_id as cust_cre4_0_0_,
customer0_.cust_source as cust_sou5_0_0_,
customer0_.cust_industry as cust_ind6_0_0_,
customer0_.cust_level as cust_lev7_0_0_,
customer0_.cust_linkman as cust_lin8_0_0_,
customer0_.cust_phone as cust_pho9_0_0_,
customer0_.cust_mobile as cust_mo10_0_0_
from
cst_customer customer0_
where
customer0_.cust_id=?
Hibernate:
select
linkmans0_.lkm_cust_id as lkm_cus10_1_0_,
linkmans0_.lkm_id as lkm_id1_1_0_,
linkmans0_.lkm_id as lkm_id1_1_1_,
linkmans0_.lkm_name as lkm_name2_1_1_,
linkmans0_.lkm_gender as lkm_gend3_1_1_,
linkmans0_.lkm_phone as lkm_phon4_1_1_,
linkmans0_.lkm_mobile as lkm_mobi5_1_1_,
linkmans0_.lkm_email as lkm_emai6_1_1_,
linkmans0_.lkm_qq as lkm_qq7_1_1_,
linkmans0_.lkm_position as lkm_posi8_1_1_,
linkmans0_.lkm_memo as lkm_memo9_1_1_,
linkmans0_.lkm_cust_id as lkm_cus10_1_1_
from
cst_linkman linkmans0_
where
linkmans0_.lkm_cust_id=?
3
3.2 fetch="select" lazy="false"
/**
* fetch="select" 默认的sql格式
* lazy="false" 不延迟加载
*/
@Test
public void run2() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//先查询1号客户
Customer c1 = session.get(Customer.class, 1L);
//看客户下所有的联系人
System.out.println(c1.getLinkmans().size());
tx.commit();
}
断点调试
执行完get(),发出了2条sql,说明,没有延迟加载。
3.3 fetch="select" lazy="extra"
/**
* fetch="select" 默认的sql格式
* lazy="extra" 极其的 延迟加载
*/
@Test
public void run3() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//先查询1号客户
Customer c1 = session.get(Customer.class, 1L);
//看客户下所有的联系人
System.out.println(c1.getLinkmans().size());
tx.commit();
}
看日志:
程序极其懒惰,我们查数量,它就发count语句。