hibernate join fetch lazy 你懂了么,反正我已经凌乱了,今天整理一下,转载一下人家的文章吧

By | 06月21日
Advertisement

fetch ,可以设置fetch = "select" 和 fetch = "join"

用一对多来举例:
fetch = "select"是在查询的时候先查询出一端的实体,然后在根据一端的查询出多端的实体,会产生1+n条sql语句;
fetch = "join"是在查询的时候使用外连接进行查询,不会差生1+n的现象。

lazy大家应该都熟悉了,就是延迟加载,可以设置lazy = "true" , lazy = "false" lazy = "proxy" 。
我在这里要说的主要问题是lazy 和fetch配合使用的问题:
1、当lazy="true" fetch = "select" 的时候 , 这个时候是使用了延迟策略,开始只查询出一端实体,多端的不会查询,只有当用到的时候才会发出sql语句去查询 ;
2、当lazy="false" fetch = "select" 的时候 , 这个时候是使没有用延迟策略,同时查询出一端和多端,同时产生1+n条sql.
3、当lazy="true"/lazy="false" fetch = "join"的时候,自己认为这个时候延迟已经没有什么用了,因为采用的是外连接查询,同时把一端和多端都查询出来了,延迟没有起作用。

Hibernate的fetch="join"和fetch="select" 的一点分析?

fetch参数指定了关联对象抓取的方式是select查询还是join查询,select方式时先查询返回要查询的主体对象(列表),再根据关联外键id,每一个对象发一个select查询,获取关联的对象,形成n+1次查询;
而join方式,主体对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询。
如果你的关联对象是延迟加载的,它当然不会去查询关联对象。
另外,在hql查询中配置文件中设置的join方式是不起作用的(而在所有其他查询方式如get、criteria或再关联获取等等都是有效的),会使用select方式,除非你在hql中指定join fetch某个关联对象。

?

fetch策略用于定义 get/load一个对象时,如何获取非lazy的对象/集合。 这些参数在Query中无效。

fetch策略用于定义 get/load一个对象时,如何获取非lazy的对象/集合。 这些参数在Query中无效。

?

查询抓取(默认的)在N+1查询的情况下是不好的,因此我们可能会要求在映射文档中定义使用连接抓取:

?

<set name="permissions"
fetch="join">
<key column="userId"/>
<one-to-many class="Permission"/>
</set
<many-to-one name="mother" class="Cat" fetch="join"/>
在映射文档中定义的抓取策略将会有产生以下影响:

通过get()或load()方法取得数据。

只有在关联之间进行导航时,才会隐式的取得数据(延迟抓取)。

条件查询

在映射文档中显式的声明 连接抓取做为抓取策略并不会影响到随后的HQL查询。

通常情况下,我们并不使用映射文档进行抓取策略的定制。更多的是,保持其默认值,然后在特定的事务中, 使用HQL的左连接抓取(left join fetch) 对其进行重载。这将通知 Hibernate在第一次查询中使用外部关联(outer join),直接得到其关联数据。 在条件查询 API中,应该调用 setFetchMode(FetchMode.JOIN)语句。

其实这并不能说明hql能够按照配置文件设置的join进行抓取,这时 第二级:topic-->forum 的抓取其实已经和hql没有关系了,因为前面已经产生了另一个select方式的抓取语句。
而是对象的关联获取,假如查询message时topic是设置为延迟加载的,那么在后面获取message.topic时,如topic.forum不延迟加载,那么topic-->forum会实现配置的join方式的抓取,这个显然和hql查询没有关系。

Similar Posts:

  • Hibernate 之 fetch lazy cascade inverse

    fetch 和 lazy 主要是用来级联查询的, 而 cascade 和 inverse 主要是用来级联插入和修改的 inverse 属性默认是false的,表示由己方来维护关系.cascade="all" 时候能级联操作(all指定了操作的程度),而none的时候只是维持两者之间的关系(如果inverse="false") 在一对多映射中,一的一方要设<set inverse="true" casecade="save-upda

  • Hibernate fetch lazy cascade inverse 关键字 【转】

    Hibernate最让人头大的就是对集合的加载形式.书看了N次了,还是没有真正理解Hibernate.所以下午专门做了下测试,对配置文件的意思加深了认识. 假设有两个表,Photos(一) --- picture(多)Photo包含picture集合 结论1: HQL代码 > fetch(配置) > lazy (配置)结论2: 默认 lazy="true"结论3: fetch 和 lazy 主要是用来级联查询的, 而 cascade 和 inverse 主要是用来级联插入和

  • hibernate中join fetch 与 join 的区别

    如果HQL使用了连接,但是没有使用fetch关键字,则生成的SQL语句虽然有连接,但是并没有取连接表的数据,还是需要单独的sql取数据,也就是 select a,b,d...中没有连接表的字段 如果集合被声明为lazy=true,在HQL中如果显式的使用 join fetch 则延迟加载失效.

  • hibernate中的lazy load还真麻烦

    To lazily load a related class, you must configure the <many-to-one> or <oneto- one> association element that references the class to use lazy loading. You must also disable proxying for the referenced class. For example, you can lazily load a

  • Hibernate数据的lazy问题,以及使用spring整合hibernate lazy的解决办法

    异常:could not initialize proxy - the owning Session was closed 其实这个异常写的非常之清楚,就是会话关闭,无法对Hibernate实体进行操作.造成这样的情况有很多,什么书写错误啊,逻辑错误啊. 但就此说一下关于lazy机制: 延迟初始化错误是运用Hibernate开发项目时最常见的错误.如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它.如果在游离状态时才

  • Hibernate fetch lazy cascade inverse 关键字

    假设有两个表,Photos(一) --- picture(多)Photo包含picture集合 结论1: HQL代码 > fetch(配置) > lazy (配置) 结论2: 默认 lazy="true" 结论3: fetch 和 lazy 主要是用来级联查询的, 而 cascade 和 inverse 主要是用来级联插入和修改的 结论4: 如果你是用spring来帮你管理你的session, 并且是自动提交,延迟加载就等于没加载~_~(当然 除非你手动重新打开sessio

  • hibernate @Nofound 与@ManyToOne fetch lazy的问题

    在hibernate上 @oneToOne, @ManyToOne, @OneToMany 这些注解上可以设置 fetch = FetchType.LAZY 但是如果在这些注解上在加上 @NotFound(action = NotFoundAction.IGNORE) 则懒加载失效, 会变成立即加载. (在程序中会带来很可怕的效应). 产生n+1查询. 所以要使用fetch = FetchType.LAZY时, 要把 @NotFound给去掉 估计hibernate在看到 @NotFound时,

  • 关于hibernate+spring使用lazy=true报错,配置opensessioninview 顺序问题

    有个struts + hibernate+spring的项目,一开始把 <set>删除掉了.现在想想直接用lazy=true就可避免性能 问题.于是乎,就把<set>加上,并把lazy设置为true.但问题来了. 页面想取得集合里的内容.取不了,后台报错: org.hibernate.LazyInitializationException: could not initialize proxy - no Session 原因是hibernate把session交给spring来管理

  • Hibernate中的lazy理解精髓(转载)

    hibernate3.0中lazy有三个值,true,false,proxy,默认的是lazy="proxy". 具体设置成什么要看你的需求,并不是说哪个设置就是最好的. 假如在student对象中包含一个head对象 如果你确定在用student对象的时候就要用到head对象里的属性,那你就设置立即加载,因为设置立即加载那么在查询student的同时就会查询student的head,hibernate就会在查询的时候关联两张表从而生成的sql就可能只有一条.而如果你设置的是延迟加载,

  • hibernate 中的 lazy="proxy" 和 lazy="no-proxy" 的区别

    Child <- many-to-one ->Parent class Child { private Parent parent; public Parent getParent (){ return this.parent;//访问了实例变量 } } class Parent { private String name; public String getName(){ return this.name;//访问了实例变量 } public void f(){ System.out.pri

Tags: