博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate抓取策略(关联级别的延迟加载)
阅读量:3907 次
发布时间:2019-05-23

本文共 9210 字,大约阅读时间需要 30 分钟。

1.3Hibernate的抓取策略(优化)

延迟加载的概述

通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式通过策略进行配置。
通过或者在上通过fetch属性进行设置
fetch和这些标签上的lazy如何设置优化发送的SQL语句
1.3.1.1什么是延迟加载
延迟加载:lazy(懒加载)。执行到该行代码的时候,不会发送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询。
1.3.1.2延迟加载的分类

  1. 类级别的延迟加载

指的是通过load方法查询某个对象的时候,是否采用延迟。session.load(Customer.class,1l);

类级别延迟加载通过上的lazy进行配置,如果让lazy失效
将lazy设置为false
将持久化类使用final修饰
Hibernate. Initialize() 立即加载

  1. 关联级别的延迟加载(重点

指的是在查询到某个对象的时候,查询其关联的对象的时候,是否采用延迟加载。

Customer customer = session.get(Customer.class,1l);
customer.getLinkMans();
----通过客户获得联系人的时候,联系人对象是否采用了延迟加载,称为是关联级别的延迟。
抓取策略往往会和关联级别的延迟加载一起使用,优化语句。
抓取策略
1.3.2.1抓取策略的概述
通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式通过策略进行配置。
通过或者上通过fetch属性进行设置
fetch和这些标签上的lazy如何设置优化发送的SQL语句

fetch和lazy

fetch:抓取策略,控制SQL语句样式,可选的值如下

select :默认值,发送普通的select语句,查询关联对象
join :发送一条迫切左外连接查询关联对象
当选择这个属性时,只有一种情况,不存在1*3 三种
subselect :发送一条子查询查询其关联对象
效率很慢,能用多表查询尽量用 多表查询
lazy:延迟加载,控制查询关联对象的时候是否采用延迟,可选的值如下
(控制发送的时机)
true :默认值,查询关联对象的时候,采用延迟加载
false :查询关联对象的时候,不采用延迟加载
extra :及其懒惰。

在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join。

配置代码:

many-to-one 上的fetch和lazy

fetch (只有两种):抓取策略,控制SQL语句格式。

select :默认值,发送普通的select语句,查询关联对象。
join :发送一条迫切左外连接。
lazy :延迟加载,控制查询关联对象的时候是否采用延迟。
proxy :默认值,proxy具体的取值,取决于另一端的上的lazy的值。
1 理解为 true:

false :查询关联对象,不采用延迟。

no-proxy :(不会使用)
在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join。

批量抓取

什么是批量抓取

在抓取的策略中有一种叫做批量抓取,就是同时查询多个对象的关联对象的时候, 可以采用批量抓取进行优化。当然这个不是特别重要。
如果要实现批量的抓取效果,可以通过配置batch-size来完成。
1.3.3.2测试批量抓取
【查询客户批量抓取练习人】
@SuppressWarnings(“unchecked”)
@Test
public void FetchDemo4() throws Exception {
/*
* 查询客户, 客户关联的联系人是否查询:
* 在Customer.hbm.xml中 集合上配置batch-size=“4”;
*
*/
//获得链接对象:
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

//查询客户: 客户关联的联系人: 	List
list = session.createQuery("from Customer").list(); for(Customer customer: list){ //打印客户的名称: System.out.println("客户的名称:"+customer.getCust_name()); //查询客户关联的联系人: for(LinkMan linkman :customer.getLinkMans()){ System.out.println("客户对应的联系人的名称:"+linkman.getLkm_name()); } } tx.commit();}

在没有设置batch-size之前运行以上代码,会出现如下的效果:

select

customer0_.cust_id as cust_id1_0_,
customer0_.cust_name as cust_nam2_0_,
customer0_.cust_source as cust_sou3_0_,
customer0_.cust_industry as cust_ind4_0_,
customer0_.cust_level as cust_lev5_0_,
customer0_.cust_phone as cust_pho6_0_,
customer0_.cust_mobile as cust_mob7_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 客户对应的联系人的名称:翠花6 客户的名称:毕老师 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=?

客户对应的联系人的名称:凤姐花5

客户对应的联系人的名称:凤姐花3
客户的名称:王八蛋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=?
客户对应的联系人的名称:蛋网吧3
查询结果分析: 目前数据库中有三个用户, 那么会发现执行代码会发生三条sql语句。我们想能不能发送一条SQL直接将两个客户的关联的联系人一起查询出来呢? 此时我们可以在标签上设置batch-size实现优化的效果。

实现配置如下:Customer.hbm.xml当中的set标签上设置:

配置后运行,发送的sql语句如下:

select        customer0_.cust_id as cust_id1_0_,        customer0_.cust_name as cust_nam2_0_,        customer0_.cust_source as cust_sou3_0_,        customer0_.cust_industry as cust_ind4_0_,        customer0_.cust_level as cust_lev5_0_,        customer0_.cust_phone as cust_pho6_0_,        customer0_.cust_mobile as cust_mob7_0_     from        cst_customer customer0_客户的名称:何老师Hibernate:     select        linkmans0_.lkm_cust_id as lkm_cus10_1_1_,        linkmans0_.lkm_id as lkm_id1_1_1_,        linkmans0_.lkm_id as lkm_id1_1_0_,        linkmans0_.lkm_name as lkm_name2_1_0_,        linkmans0_.lkm_gender as lkm_gend3_1_0_,        linkmans0_.lkm_phone as lkm_phon4_1_0_,        linkmans0_.lkm_mobile as lkm_mobi5_1_0_,        linkmans0_.lkm_email as lkm_emai6_1_0_,        linkmans0_.lkm_qq as lkm_qq7_1_0_,        linkmans0_.lkm_position as lkm_posi8_1_0_,        linkmans0_.lkm_memo as lkm_memo9_1_0_,        linkmans0_.lkm_cust_id as lkm_cus10_1_0_     from        cst_linkman linkmans0_     where        linkmans0_.lkm_cust_id in (            ?, ?, ?        )

客户对应的联系人的名称:翠花2

客户对应的联系人的名称:翠花4
客户的名称:毕老师
客户对应的联系人的名称:凤姐花2
客户对应的联系人的名称:凤姐花6
客户的名称:王八蛋3
客户对应的联系人的名称:蛋网吧3
分析运行的sql语句: 发送的sql语句发生了变化,当数据量越大的时候, 效果越是明显。这是在查询所有的客户的时候批量抓取联系人。那么如果我们要实现查询多个联系人的时候,抓取联系人对应的客户呢? 同样需要设置batch-size。但是不是在上设置, 还是在客户的一端的 上设置即可。
【查询联系人批量抓取客户】
@SuppressWarnings(“unchecked”)
@Test
public void FetchDemo5() throws Exception {
/*
* 查询联系人,批量抓取客户
* 在Customer.hbm.xml中
* 注意: 如果在查询的过程当中出现了NullPointerException: 说明联系人的外键是null,没有关联的用户信息。
*/
//获得链接对象:
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

//查询联系人信息: 	List
list = session.createQuery("from LinkMan").list(); //遍历联系人信息: for(LinkMan linkMan : list){ System.out.println(linkMan.getLkm_name()); //打印联系人对应的客户的名称 System.out.println(linkMan.getCustomer().getCust_name()); } tx.commit();}

运行的结果分析:

select        linkman0_.lkm_id as lkm_id1_1_,        linkman0_.lkm_name as lkm_name2_1_,        linkman0_.lkm_gender as lkm_gend3_1_,        linkman0_.lkm_phone as lkm_phon4_1_,        linkman0_.lkm_mobile as lkm_mobi5_1_,        linkman0_.lkm_email as lkm_emai6_1_,        linkman0_.lkm_qq as lkm_qq7_1_,        linkman0_.lkm_position as lkm_posi8_1_,        linkman0_.lkm_memo as lkm_memo9_1_,        linkman0_.lkm_cust_id as lkm_cus10_1_     from        cst_linkman linkman0_翠花0Hibernate:     select        customer0_.cust_id as cust_id1_0_0_,        customer0_.cust_name as cust_nam2_0_0_,        customer0_.cust_source as cust_sou3_0_0_,        customer0_.cust_industry as cust_ind4_0_0_,        customer0_.cust_level as cust_lev5_0_0_,        customer0_.cust_phone as cust_pho6_0_0_,        customer0_.cust_mobile as cust_mob7_0_0_     from        cst_customer customer0_     where        customer0_.cust_id=?何老师翠花1何老师翠花2何老师Hibernate:     select        customer0_.cust_id as cust_id1_0_0_,        customer0_.cust_name as cust_nam2_0_0_,        customer0_.cust_source as cust_sou3_0_0_,        customer0_.cust_industry as cust_ind4_0_0_,        customer0_.cust_level as cust_lev5_0_0_,        customer0_.cust_phone as cust_pho6_0_0_,        customer0_.cust_mobile as cust_mob7_0_0_     from        cst_customer customer0_     where        customer0_.cust_id=?毕老师蛋网吧Hibernate:     select        customer0_.cust_id as cust_id1_0_0_,        customer0_.cust_name as cust_nam2_0_0_,        customer0_.cust_source as cust_sou3_0_0_,        customer0_.cust_industry as cust_ind4_0_0_,        customer0_.cust_level as cust_lev5_0_0_,        customer0_.cust_phone as cust_pho6_0_0_,        customer0_.cust_mobile as cust_mob7_0_0_     from        cst_customer customer0_     where        customer0_.cust_id=?王八蛋3蛋网吧2王八蛋3配置批量抓取:运行结果如下:     select        linkman0_.lkm_id as lkm_id1_1_,        linkman0_.lkm_name as lkm_name2_1_,        linkman0_.lkm_gender as lkm_gend3_1_,        linkman0_.lkm_phone as lkm_phon4_1_,        linkman0_.lkm_mobile as lkm_mobi5_1_,        linkman0_.lkm_email as lkm_emai6_1_,        linkman0_.lkm_qq as lkm_qq7_1_,        linkman0_.lkm_position as lkm_posi8_1_,        linkman0_.lkm_memo as lkm_memo9_1_,        linkman0_.lkm_cust_id as lkm_cus10_1_     from        cst_linkman linkman0_翠花0Hibernate:     select        customer0_.cust_id as cust_id1_0_0_,        customer0_.cust_name as cust_nam2_0_0_,        customer0_.cust_source as cust_sou3_0_0_,        customer0_.cust_industry as cust_ind4_0_0_,        customer0_.cust_level as cust_lev5_0_0_,        customer0_.cust_phone as cust_pho6_0_0_,        customer0_.cust_mobile as cust_mob7_0_0_     from        cst_customer customer0_     where        customer0_.cust_id in (            ?, ?, ?        )

分析结果: 发送的语句和之前发生了变化, 这些优化都是Hibernate提升自身性能的手段。

转载地址:http://ywqen.baihongyu.com/

你可能感兴趣的文章
HDU 1559 最大子矩阵
查看>>
Open Judge 4010 :2011
查看>>
百练OJ-2815 城堡问题【DFS】
查看>>
CODE[VS] 1025 选菜 【背包】
查看>>
POJ 1724 ROADS【DFS+剪枝】
查看>>
AOJ 847 整数拆段
查看>>
AOJ 848 分数拆分
查看>>
UVA 133 The Dole Queue 【约瑟夫环】
查看>>
XDOJ 1208 B.笑爷买房 【DFS】
查看>>
部门年度工作总结的内容
查看>>
pandas学习笔记
查看>>
Numpy笔记
查看>>
正则表达式
查看>>
python线程进程笔记
查看>>
TensorFlow初学者必须了解的55个经典案例
查看>>
机器学习笔记
查看>>
数十种TensorFlow实现案例汇集:代码+笔记
查看>>
python记录的错误与知识
查看>>
内核中各种套接字的关系
查看>>
linux sysctl 参数实现 暨 ip_forward参数对Linux内核转发影响分析
查看>>