Hibernate的抓取策略---Hibernate查询方式的优化 延迟加载 + 抓取策略

}

在这里插入图片描述

(3)extra:及其懒惰

在这里插入图片描述

当通过查询到customer去获取对应联系人的信息的时候,如果只是查询数量,懒加载extra,只会发送select count() from ,来统计数量,不会向上面flase的将对应的联系人都查询到。

@Test

// fetch=“select” lazy=“extra”

public void demo04() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

// 查询1号客户

Customer customer = session.get(Customer.class, 1l);// 发送一条查询1号客户的SQL语句

System.out.println(customer.getLinkMans().size());//发送select count() from …

tx.commit();

}

在这里插入图片描述

(4)join:发送一条迫切左外链接查询关联对象

当fetch="join"的时候在lazy当中配置都是没有作用的 --------> lazy失效

在这里插入图片描述

@Test

// 设置fetch=“join” lazy=true

public void demo05() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

Customer customer = session.get(Customer.class, 1l);// 发送一条迫切左外链接查询记录

System.out.println(customer.getCust_name());

System.out.println(customer.getLinkMans().size());//不发送

tx.commit();

}

在这里插入图片描述

设置fetch=“join” lazy=“false”

在这里插入图片描述

在这里true和false的效果一样,因为join的功能就是迫切左外链接,查询当前对象,并查询对应左边关联的对象,已经全部查询到,懒加载失效

(5)设置fetch=“subselect” lazy=“true”> subselect通过子查询来查找对应的联系人

先发送SQL查询对应的客户,然后在获取对应联系人信息的时候再发送一条SQL

在这里插入图片描述

@Test

// 设置fetch=“subselect” lazy=“true”

public void demo07() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

List list = session.createQuery(“from Customer”).list();//发送查询所有客户的SQL语句

for (Customer customer : list) {

System.out.println(customer.getCust_name());

System.out.println(customer.getLinkMans().size());//发送的一条子查询,通过对象的外键匹配对应的联系人

}

tx.commit();

}

在这里插入图片描述

在这里插入图片描述

(6)设置fetch=“subselect” lazy=“false” 查询客户并同时查询对应的联系人

发送查询客户的语句,通过子查询的方式统计对应的数据

在这里插入图片描述

@Test

// 设置fetch=“subselect” lazy=“false”

public void demo08() {

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());

System.out.println(customer.getLinkMans().size());

}

tx.commit();

}

在这里插入图片描述

在这里插入图片描述

(7)在实际的开发当中,我们一般都采用默认值。fetch=select lazy=true

如果有特殊的需求,可能需要配置join。

3、< many-to-one > 上的fetch和lazy
fetch:抓取策略,控制SQL语句的个数

select :(默认值):发送普通的select语句来,查询对应关联的对象

join:发送一条迫切左外链接

lazy:延迟加载,控制查询关联对象的时候是否采用延迟

proxy:(默认值):proxy具体的取值,取决于我们另一端上< class >上的lazy的值。如果class上的lazy是true

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

no-proxy:(不会使用)

测试方法:通过联系人查询客户

在LinkMan.hbm.xml当中配置对应的信息

(1)测试< many-to-one > 上的fetch和lazy默认值

先将Customer.hbm.xml当中的类级别的懒加载和抓取策略上的set的fecth和lazy的属性全部去掉

测试

先发送一条查询联系人的SQL语句,然后再发送一条查询下客户的SQL语句

@Test

// 默认值LinkMan当中的many-to-one上的默认值

public void demo01() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

LinkMan linkMan = session.get(LinkMan.class, 1l);//发送一条查询联系人的语句

System.out.println(linkMan.getLkm_name());

System.out.println(linkMan.getCustomer().getCust_name());//发送一条查询客户的SQL语句

tx.commit();

}

在这里插入图片描述

然后在LinkMan.hbm.xml当中配置, <many-to-one>配置fetch="select" lazy="proxy"

在这里插入图片描述

再次运行代码,结果和上述的结果一直则,证明,其默认值为fetch="select" lazy="proxy"

(2)配置< many-to-one >上 <many-to-one>配置fetch="select" lazy="false"

发送SQL查询联系人的信息并发送SQL查询对应的客户

@Test

// 配置fetch=“select” lazy=“false”

public void demo03() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

//发送两个select语句

LinkMan linkMan = session.get(LinkMan.class, 1l);//发送SQL查询联系人的信息并发送SQL查询对应的客户

System.out.println(linkMan.getLkm_name());

System.out.println(linkMan.getCustomer().getCust_name());

tx.commit();

}

在这里插入图片描述

(3)< many-to-one >配置fetch=“join” lazy=“失效”

发送一条迫切左外链接去查询联系人所关联的客户

@Test

// 配置fetch=“join” lazy=“失效”

public void demo04() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

// 发送一条迫切左外链接去查询联系人所关联的客户

LinkMan linkMan = session.get(LinkMan.class, 1l);

System.out.println(linkMan.getLkm_name());

System.out.println(linkMan.getCustomer().getCust_name());

tx.commit();

}

在这里插入图片描述

false和proxy效果一样

在这里插入图片描述

(4)proxy具体的取值,取决于我们另一端上< class >上的lazy的值。如果class上的lazy是true

a、设置 LinkMan.hbm.xml和Customer.hbm.xml

发送两条查询SQL语句

LinkMan.hbm.xml

在这里插入图片描述

Customer.hbm.xml

在这里插入图片描述

当中Customer.hbm.xml当中lazy为ture的时候,相当于< many-to-one >当中的lazy=“false”

// 配置fetch=“select” lazy=“proxy”

public void demo02() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

LinkMan linkMan = session.get(LinkMan.class, 1l);// 发送一条查询联系人的语句

System.out.println(linkMan.getLkm_name());

System.out.println(linkMan.getCustomer().getCust_name());

tx.commit();

}

在这里插入图片描述

b、 LinkMan.hbm.xml当中的值不变,改变Customer.hbm.xml当中的数值

在这里插入图片描述

当class当中的lazy等于false的时候,当中< many-to-one >相当于lazy=“false”

再次运行上面代码,同时发送两个查询SQL语句,查询联系并查询客户

在这里插入图片描述

三、批量抓取策略。


1、什么是批量抓取

一批关联对象一起进行抓取,batch-size

一次获取多个客户的联系人信息

2、测试批量抓取:通过客户获取对应的联系人
(1)默认情况下:通过客户获取对应的联系人

@Test

// 在获取客户的时候同时批量去抓取联系人

public void demo01() {

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();

}

会发送很多查询语句,效率比较底下

在这里插入图片描述

(2)在一 的一方配置batch-size=“”

Customer.hbm.xml

batch-size="“代表当前对象是几个为一组发送SQL语句,超出的自动增加发送SQL语句的数量

发送SQL数量等于通过外键要查询的数据总数除以batch-size=”" 当中的数,不够加一

batch-size=""等于外键种类数量是最好的情况

在这里插入图片描述

@Test

// 在获取客户的时候同时批量去抓取联系人

public void demo01() {

Session session = HibernateUtils.getCurrentSession();

Transaction tx = session.beginTransaction();

List list = session.createQuery(“from Customer”).list();

for (Customer customer : list) {

System.out.println(“-------------------------------”);

System.out.println(customer.getCust_name());

System.out.println(“-------------------------------”);

for (LinkMan linkman : customer.getLinkMans()) {

System.out.println(linkman.getLkm_name());

}

}

tx.commit();

}

在这里插入图片描述

在这里插入图片描述

3、测试批量抓取:在获取联系人的时候同时批量去抓取客户
(1)默认情况

@Test

// 在获取联系人的时候同时批量去抓取客户

public void demo02() {

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();

}

发送了五条查询语句

查询所有联系人,然后根据外键查询对应的客户

在这里插入图片描述

(2)虽然控制的时通过联系人查询对应客户,但是也得在客户上去配置对应信息。

在Customer.hbm.xml上的配置

在这里插入图片描述

batch-size=“3"同时根据3个id进行查询

发送SQL数量等于通过外键要查询的数据总数除以batch-size=”" 当中的数,不够加一

batch-size=""等于外键种类数量是最好的情况

@Test

// 在获取联系人的时候同时批量去抓取客户

//在Customer.hbm.xml上的配置

public void demo02() {

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());//获取到所有的联系人

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
nkMan.getLkm_name());//获取到所有的联系人

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-p1gyBtVN-1715690923295)]

[外链图片转存中…(img-LdJDp6LD-1715690923296)]

[外链图片转存中…(img-Vc5mvk5d-1715690923297)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值