`
janh
  • 浏览: 18273 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

惊喜,实现hibernate中一对一关联的从方的延迟加载的一种方法

    博客分类:
  • java
阅读更多
关于hibernate中一对一关联时,从方不能实现延迟加载好对帖子里都讲到了,关键是 外键列是在从方表中的,由从方指向主方,加载主方时必须要查询从方表才能知道对应的从方是否存在。

引用
关于one-to-one关联的从方不能lazy loading是由one-to-one的机制造成的,比如user和contact是一对一,user是主,contact是从,约束依赖于user,那么在数据库中,contact表中应该有一个外键字段指向user表的主键。

当加载contact对象时,从contact表的记录中就可以得到user记录的id,这和多对一是一样的,就可以知道user对象是否存在,不存在则user为null,存在就生成代理对象,所以可以实现主方的延迟加载。

当加载user对象时,从user表记录中没有办法知道这个contact从方是否存在,它就不能确定是用null还是生成代理对象来代替contact对象,因为代理对象一定 != null,所以必须要查询contact表,查询这个从方是否存在。

基于上面的情况,所以我现在一般不用one-to-one关联,倒不是一定要延迟加载,还有n+1次问题等等,处理起来比较麻烦,宁可用user到contact的多对一关联,contact为一方,虽然意义上好像反了,但是从user对象可以很方便的得到contact对象,实际上也都是从user来获取contact信息的,延迟加载也没问题。

上面一段描述时实际是将外键列放在主方user表中来指向contact表,来解决contact不能延迟加载的问题的。
那么按照正常的contact表中外键列指向user表,到底能不能实现加载user时contact的延迟加载呢?


能不能在加载主表user表时同时查询出对应的contact表的Id呢?
一个偶然的机会,我测试了类似以下的配置:
User类的映射文件中:
<many-to-one name="contact" class="com.xxx.Contact" >
            <formula>(select c.CONTACT_ID from CONTACT c where c.USER_ID = USER_ID)</formula>
        </many-to-one>

在User类中有一个contact属性对象,但是在user表中并没有一个外键指向contact表,相反是contact表中的外键列USER_ID指向user表的主键,在user类的映射文件中用一句子查询来代替contact对象,返回的是与user表对应的contact的id值。
测试通过,可以实现user.contact的延迟加载!!
加载user时hibernate生成的sql语句类似如下:
select user0_.USER_ID as USER1_0_1_, user0_.ACCOUNT as ACCOUNT0_1_, user0_.NAME as NAME0_1_, ...... , (select c.CONTACT_ID from CONTACT c where c.USER_ID = user0_.USER_ID) as formula0_1_  from USER user0_ where ......

当那个子查询返回null时,user.contact为null;当那个子查询返回一个值时user.contact为Contact类的代理对象,代理对象的id是该子查询的返回值;当子查询返回值多于一个时报错。再获取user.contact的其他属性时就像普通延迟加载的多对一关联一样没有任何问题。

这种配置方式与普通的多对一配置相比,最大的不同点在于“多方”表中并没有一个外键列指向“一方”的主键,而是用一个子查询的返回值来代替这个外键列值。

后面继续测试了多对一的lazy和fetch的各种配置,可喜的是完全与普通的多对一关联方式一样,可以实现延迟加载、非延迟加载、select方式抓取以及连接方式抓取,并且在get、hql查询、Criteria查询中都没有问题,看来hibernate完全将这个子查询代替了本来的外键列值。

以上测试在hibernate版本3.2.2中通过。

这种方法的最大好处在于可以实现两个方向的多对一对象关联(两个方向都是多对一),而数据库中只需要单向的指向约束,没有相互指向约束引起的问题。相当于双向一对一。也给非主外键关联提供了另一种方法。
分享到:
评论

相关推荐

    hibernate一对一之唯一外键关联(双向关联)

    - 在一对一关联中,唯一外键关联是指在一个实体中定义了另一个实体的主键作为其字段,形成外键约束,确保了数据的一致性和完整性。 3. **双向关联与单向关联** - **单向关联**:只有一方知道另一方的存在,例如...

    hibernate 延迟加载深入剖析

    本文将对Hibernate中的延迟加载技术进行深入剖析,帮助读者更好地理解和运用这项技术。 #### 二、基本概念 ##### 2.1 什么是延迟加载? 延迟加载是指在访问关联数据或集合数据时,只有在真正需要使用这些数据时才...

    hibernate延迟加载解决

    延迟加载是一种优化技术,在软件开发中广泛应用于各种场景,尤其在数据库交互中尤为重要。其核心思想是仅在确实需要某个资源时才加载它,而非一开始就加载所有相关的数据。这种方式能够显著减少初始加载时间和内存...

    Hibernate延迟加载以及利用Spring

    在Hibernate中,延迟加载主要用于关联对象的加载,例如一对多或多对多的关系。默认情况下,当Hibernate查询一个实体时,会同时加载与该实体相关的所有关联对象。但在某些场景下,我们可能并不需要立即获取这些关联...

    Hibernate一对一关联映射(注解)

    ### Hibernate一对一关联映射原理 一对一关联映射是指在数据库中两个表之间存在一对一的关系,例如,一个人只有一个身份证,一个身份证也只属于一个人。在Hibernate中,我们可以通过@OneToOne注解来实现这种映射。 ...

    Hibernate ORM - 一对一主键关联关系

    - **外键约束**:在一对一关联中,如果不使用共享主键,可以创建外键约束,但这样就不再是真正的“主键关联”。 - **懒加载与立即加载**:默认情况下,关联对象会在加载主对象时一同加载,这称为“立即加载”。若...

    Hibernate集合属性的延迟加载.doc

    在 Hibernate 框架中,延迟加载(Lazy Loading)是一种优化数据访问性能的重要技术。它允许我们只在真正需要数据时才从数据库加载,避免一次性加载大量数据导致的内存消耗和性能瓶颈。当我们处理与实体相关的集合...

    Hibernate ORM - 一对一外键关联关系

    1. **一对一外键关联配置**:在Hibernate中,可以通过在映射文件中添加`&lt;one-to-one&gt;`标签或在实体类上使用`@OneToOne`注解来定义一对一关联。关联的外键通常位于被引用的实体(“一对一”关系的“一”端)中。 2. ...

    Hibernate 延迟加载剖析与代理模式应用

    在Hibernate中,当加载一个实体时,如果实体的某些属性被配置为延迟加载,那么Hibernate会生成一个代理对象来代替真实的集合或关联实体。这个代理对象包含了加载数据的方法。当应用程序尝试访问这些延迟加载的属性时...

    hibernate 延迟加载.docx

    3. 多对一关联:`lazy="proxy"`(延迟加载)、`lazy="no-proxy"`(无代理延迟加载)或`lazy="false"`(立即加载),默认为`proxy`。 **`load()`与`get()`的区别** 1. **加载方式**:`load()`采用延迟加载,`get()`...

    Hibernate 延迟加载

    - **延迟加载**:与之相反,延迟加载仅在真正需要某个对象的关联对象时,才从数据库中加载这些关联对象。这意味着,只有当代码实际访问了对象的关联属性时,Hibernate才会触发数据库查询。这种方式显著减少了数据库...

    Hibernate延迟加载

    在Hibernate中,延迟加载分为三种主要类型:实体对象的延迟加载、集合类型的延迟加载以及属性延迟加载(在Hibernate 3及以上版本支持)。 ### 实体对象的延迟加载 在Hibernate映射文件中,可以通过将`&lt;class&gt;`标签...

    hibernate延迟加载

    从 Hibernate 3 开始,除了实体对象和集合之外,还可以实现对属性的延迟加载。这使得可以在实体对象已经加载的情况下,只加载需要的特定属性,进一步提高了性能。 ##### 配置示例 ```xml &lt;hibernate-mapping&gt; ...

    hibernate延迟加载技术详细解

    在 Hibernate 框架中,延迟加载(Lazy Loading)是一种非常重要的优化技术,它能够有效地减少数据库查询次数,提高应用性能。通常,在多对多或者一对多的关系中,延迟加载能够避免 N+1 查询问题。本文将详细探讨 ...

    hibernate之一对一关联映射

    本篇将详细探讨 Hibernate 之中的一对一关联映射,这是一种常见的关系数据库设计模式,在实际开发中经常被用到。 一对一关联映射在Hibernate中表示两个实体类之间存在一对一的关系,也就是说,每个实体类的对象只...

    hibernate的一对一

    【hibernate的一对一】关系映射是...以上就是关于Hibernate中一对一关联的基本概念、配置方式以及注意事项的详细解释。在实际开发中,结合具体的业务场景,灵活运用这些知识,可以有效地管理和维护复杂的实体关系。

    详解Hibernate一对一映射配置

    在Java持久化框架Hibernate中,一对一(One-to-One)映射是对象关系映射的一种常见方式,用于表示两个实体之间一对一的关系。这种关系通常出现在一个实体的实例只能与另一个实体的单个实例相关联的情况。下面我们将...

    hibernate中的 一对一唯一外键双向关联

    在Hibernate中,一对一关联可以通过以下两种方式建立: 1. **通过主键关联(Primary Key Join)**:这种关联方式下,一方的主键同时也是另一方的外键。这种方式通常用于当两个表有共享主键的情况。 2. **通过唯一...

Global site tag (gtag.js) - Google Analytics