一.概述

我们先来谈谈检索数据时的两个问题:

1.不浪费内存   2.更好的检索效率

以上说的问题都是我们想要避免的,接下来就引出了我们要讨论的话题---------------hibernate检索策略

二.hibernate检索策略分为三种:

1.类级别的检索策略

2.一对多和多对多检索策略

3.多对一和一对一关联的检索策略

(1)类级别的检索策略分为立即检索和延迟检索,默认为延迟检索。

立即检索:立即加载检索方法指定的对象,立即发送SQL.

延迟检索:延迟加载检索方法指定的对象,在使用具体的对象时,再进行加载,发送SQL.

lazy有两个取值:false(立即加载) 和 true(延迟加载)

讨论一:当用get()方法检索数据时,在类级别检索策略不管是不是延迟加载都会立即检索

接下来看看代码实现是不是跟我说的一样:

配置文件中:

测试类代码:

 @Test
public void select1(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
House house = session.get(House.class, );
System.out.println("===========================");
// System.out.println(house.getType().getName());
tx.commit();
HibernateUtil.closeSession();
}

接下来看看测试的效果:

接下来我们把lazy设为true:

效果:

大家注意没,测试类有一行代码我是注释掉的,为的就是让我们很好的理解,如果我把下面的代码放开是什么效果呢?大家要注意现在我们的查询是get()方法:

我们得到的结果是一样的,这样就说明了当使用类级别检索时,使用get()方法都会立即加载。

讨论二:我们在来看看load()方法(也是类级别的检索),我们只需要修改代码即可:

   @Test
public void select1(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
House house = session.load(House.class, );
System.out.println("=========lazy:false==================");
//System.out.println(house.getType().getName());
tx.commit();
HibernateUtil.closeSession();
}

lazy:false时:

我们把lazy设为true时效果如下:

我们看到只打印了分割线,到这里我们可以看出get()和load()方法在类级别检索时的区别,接下来我们看看当放开注释的代码时会发生什么呢?

我们可以很直观的看出来,得到的结果不一样,当延迟加载的情况下,当我们有后续操作时才会向数据库发送SQL,查询结果。而立即加载在我们有后续操作之前,已经先查询了一道,然后再根据后续操作查询结果。

通过以上我们做的测试,我们可以得出一个结论:

当类级别检索时:get()方法不管延迟加载还是延迟加载都会先查询一道,有后续操作再向数据库发送SQL,得到结果。

load()方法:当是延迟加载的情况下,有后续操作才会向数据库发送SQL,查询结果。

当是立即加载的情况下,就和get()方法一样,先查询一道,有后续从操作在查询。

总的来说,load()方法受类级别检索策略影响,get()方法不受影响。

(2)一对多和多对多检索策略

在映射文件中,用<set>元素来配置一对多和多对多关联关系

lazy取值有:false(立即加载),true(延迟加载)和extra(加强延迟加载)

配置文件:

测试类代码:

 @Test
public void select(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
House house = session.load(House.class, 1);
System.out.println("==========lazy:false===================");
System.out.println(house.getClass());
// System.out.println(house.getTitle());
tx.commit();
HibernateUtil.closeSession();
}

先来看看当我们使用load()加载数据时,我们输出的结果:

当lazy取值为false:

当lazy取值为true:

都没有后续操作时,没有不同。接下来我们看一下当有后续操作时(解开注释的代码),会发生什么?

lazy:true时:

lazy为false时:

我们可以明显的看出这两个的不同,延迟加载时发送了一条SQL,立即加载时发送了两条SQL,延迟加载的后续操作是根据你的条件查询的,立即加载根据你的条件查询之后,如果有与之相关的表,也会进行两表查询。

get()方法获取时,没有后续操作:

lazy:true

lazy:false:

当有后续操作时,看看是什么情况?

lazy:true时,

lazy:false时,

由此可以看出,当使用get()方法时,不管有没有后续操作,都会先向数据库发送SQL语句,保存对象的信息,而且我们也看出来不管load()和get()在立即加载情况下,会向数据库发送SQL,根据你查询对象所关联的表的个数来决定向数据库发送几条SQL语句,(我列举的例子是发送两条)。

当lazy取值为extra(加强延迟加载),接下来的测试,我们主要探讨的是获取集合的size()时有什么不同:

配置文件:

测试类代码:

 @Test
public void select(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Users users = session.get(Users.class, );
System.out.println("==========lazy:true===================");
System.out.println(users.getClass());
//System.out.println(users.getHouse().size());
tx.commit();
HibernateUtil.closeSession();
}

先来探讨没有后续操作时,get()和load()方法

get()方法:

load()方法:

当有后续操作时,get()和load()方法的结果:

get()方法:

load()方法:

当有后续操作时,get()和load()方法向数据库索要数据的语句相同。不同的是get()方法不管有没有后续操作都会向数据库发送SQL,

而load()方法是在你用到它的属性的时候才会向数据库发送SQL。

最后看一下当取值为true 和 false时语句有什么不同?

在延迟加载的情况下:

get()方法获取数据                                             load()方法获取数据

在立即加载的情况下:

get()方法加载数据:                                                 load()方法加载数据:

这里写的可能有点啰嗦了,但是总的一句话:

Extra:极其懒惰,只有访问集合对象的属性时才会加载,访问集合本身的属性时(例如,集合大小,生成count),不会立即加载。

最后来给大家总结一下:

类级别检索策略:仅仅适用于load()加载

好了,就讨论到这里吧,可能我写的也不是太好,这就需要自己下来多多练习,熟练实践.......

Hibernate 一对多,多对多,多对一检索策略的更多相关文章

  1. 攻城狮在路上(壹) Hibernate(十二)--- Hibernate的检索策略

    本文依旧以Customer类和Order类进行说明.一.引言: Hibernate检索Customer对象时立即检索与之关联的Order对象,这种检索策略为立即检索策略.立即检索策略存在两大不足: A ...

  2. Hibernate的检索策略和优化

    一.检索策略概述 当我们实现了一对多或者多对多的映射后,在检索数据库时需要注意两个问题: 1.使用尽可能小的内存:当 Hibernate 从数据库中加载一个客户信息时, 如果同时加载所有关联这个客户的 ...

  3. 【Hibernate】Hibernate系列5之检索策略

    检索策略 5.1.类级别检索策略 5.2.set多对多.一对多检索策略 5.3.多对一.一对一检索策略 HQL作用: http://zhidao.baidu.com/link?url=dnAdJWR7 ...

  4. Hibernate 一对多/多对多

    一对多关联(多对一): 一对多关联映射: 在多的一端添加一个外键指向一的一端,它维护的关系是一指向多 多对一关联映射: 咋多的一端加入一个外键指向一的一端,它维护的关系是多指向一 在配置文件中添加: ...

  5. 【Jpa hibernate】一对多@OneToMany,多对一@ManyToOne的使用

    项目中使用实体之间存在一对多@OneToMany,多对一@ManyToOne的映射关系,怎么设置呢? GitHub地址:https://github.com/AngelSXD/myagenorderd ...

  6. hibernate一对多和多对一配置

    public class Dept { private int deptId; private String deptName; // [一对多] 部门对应的多个员工 private Set<E ...

  7. Java进阶知识10 Hibernate一对多_多对一双向关联(Annotation+XML实现)

    本文知识点(目录): 1.Annotation 注解版(只是测试建表)    2.XML版 的实现(只是测试建表)    3.附录(Annotation 注解版CRUD操作)[注解版有个问题:插入值时 ...

  8. hibernate(八) Hibernate检索策略(类级别,关联级别,批量检索)详解

    序言 很多看起来很难的东西其实并不难,关键是看自己是否花费了时间和精力去看,如果一个东西你能看得懂,同样的,别人也能看得懂,体现不出和别人的差距,所以当你觉得自己看了很多书或者学了很多东西的时候,你要 ...

  9. Hibernate检索策略之延迟加载和立即加载

    延迟加载:延迟加载(lazy load懒加载)是当在真正需要数据时,才执行SQL语句进行查询.避免了无谓的性能开销. 延迟加载分类:  1.类级别的查询策略 2.一对多和多对多关联的查询策略 3.多对 ...

随机推荐

  1. 点击按钮添加一行,和本行的删除功能,序号变动,name属性更改

    <!--html结构--> <div> <input type="button" value="添加一行" onclick=&qu ...

  2. win10打开移动热点让手机连接上网教程

    概述: 为什么要这么做呢? 我笔记本插网线可以上网,但是没有买猫盒,所以只能pc开热点,让手机上网. 过程如下: 1开启移动热点,设置密码 1.1开启移动热点,截图如下: 1.2设置热点名称,密码 2 ...

  3. 2018年10月19 手记 - 身为开发者的我de窘境

    从10月1国庆过完节回来,那已经是7号了,之后便开始紧锣密鼓的筹划着接下来11月份的公司组织的对外活动,这边新来的产品对产品或者说对任务很是负责,并且策划了很多的方案,并且乐意站在我们开发的角度上去考 ...

  4. win7 设置docker加速器

    本来专门已经有了一个源于docker加速器的了,公司的电脑是mac,配置很简单,但是我自己的电脑是win7,在实际操作的时候还真是累啊,官网的教程不知道为什么没起效果,所以最终还是找了其他人发的帖,可 ...

  5. pycharm下运行unittest的问题

    环境: 系统:window7 64 软件:pycharm 版本:2016.3.2 问题描述: 使用unittest类的时候出现问题,问题截图如下 Pycharm 2016.2执行单元测试遇到如下问题: ...

  6. Golang开发环境搭建

    1.下载golang安装包: 下载地址:https://golang.google.cn/dl/ 2.安装Eclipse 下载goclipse 插件 3.配置 Go 的编译器 4.写代码. packa ...

  7. leetcode有意思的题目总结

    231. 2的幂 2^3=8 得  8是2的幂 判断一个整数是不是2的幂,可根据二进制来分析.2的幂如2,4,8,等有一个特点: 二进制数首位为1,其他位为0,如2为10,4为100 2&(2 ...

  8. SAP Sybase IQ 操作基础

    1.启动 source IQ-16_0.sh 命令行查看安装程序是否成功 start_iq -v2 2.数据库.表空间 start_iq -n utility_db dbisql -c 'uid=db ...

  9. selenium+Python(Js处理浏览器滚动条)

    控制浏览器滚动条 有时候我们需要控制页面滚动条上的滚动条,但滚动条并非页面上的元素,这个时候就需要借助 js 是来进行操作.一般用到操作滚动条的会两个场景: 注册时的法律条文需要阅读,判断用户是否阅读 ...

  10. java跨库事务Atomikos

    1:引入额外的jar <dependency> <groupId>com.atomikos</groupId> <artifactId>transact ...