Hibernate是如何延迟加载的

Hibernate延迟加载机制深度解析 延迟加载(Lazy Loading)是Hibernate的一种性能优化策略,它推迟对象关联数据的加载时机,只有在真正访问这些关联数据时才会从数据库加载。这种机制有效减少了不必要的数据库查询,显著提升了应用性能。默认使用LAZY:除明确需要立即加载的关联外,全部配置为延迟加载合理使用JOIN FETCH:对确实需要立即加载的关联使用关注Session生命周期:确保在Session打开时访问延迟属性监控查询数量:定期检查是否产生N+1问题考虑DTO投影:复杂查询使用专用DTO代替实体测试不同场景。 阅读详情
 

Hibernate对象关系映射提供延迟的与非延迟的对象初始化。非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来。这有时会导致成百的(如果不是成千的话)select语句在读取对象的时候执行。这个问题有时出现在使用双向关系的时候,经常会导致整个数据库都在初始化的阶段被读出来了。当然,你可以不厌其烦地检查每一个对象与其他对象的关系,并把那些最昂贵的删除,但是到最后,我们可能会因此失去了本想在ORM工具中获得的便利。一个明显的解决方法是使用Hibernate提供的延迟加载机制。这种初始化策略只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来。这个过程对开发者来说是透明的,而且只进行了很少的数据库操作请求,因此会得到比较明显的性能提升。这项技术的一个缺陷是延迟加载技术要求一个Hibernate会话要在对象使用的时候一直开着。这会成为通过使用DAO模式将持久层抽象出来时的一个主要问题。为了将持久化机制完全地抽象出来,所有的数据库逻辑,包括打开或关闭会话,都不能在应用层出现。最常见的是,一些实现了简单接口的DAO实现类将数据库逻辑完全封装起来了。一种快速但是笨拙的解决方法是放弃DAO模式,将数据库连接逻辑加到应用层中来。这可能对一些小的应用程序有效,但是在大的系统中,这是一个严重的设计缺陷,妨碍了系统的可扩展性。在Web层进行延迟加载幸运的是,Spring框架为Hibernate延迟加载与DAO模式的整合提供了一种方便的解决方法。对那些不熟悉Spring与Hibernate集成使用的人,我不会在这里讨论过多的细节,但是我建议你去了解Hibernate 与Spring集成的数据访问。以一个Web应用为例,Spring提供了OpenSessionInViewFilter和 OpenSessionInViewInterceptor。我们可以随意选择一个类来实现相同的功能。两种方法唯一的不同就在于interceptor 在Spring容器中运行并被配置在web应用的上下文中,而Filter在Spring之前运行并被配置在web.xml中。不管用哪个,他们都在请求将当前会话与当前(数据库)线程绑定时打开Hibernate会话。一旦已绑定到线程,这个打开了的Hibernate会话可以在DAO实现类中透明地使用。这个会话会为延迟加载数据库中值对象的视图保持打开状态。一旦这个逻辑视图完成了,Hibernate会话会在Filter的doFilter方法或者Interceptor的postHandle方法中被关闭。下面是每个组件的配置示例: Interceptor的配置: Filter的配置 hibernateFilter org.springframework.orm.hibernate.support.OpenSessionInViewFilter hibernateFilter *. spring 实现Hibernate的Dao接口来使用打开的会话是很容易的。事实上,如果你已经使用了Spring框架来实现你的Hibernate Dao,很可能你不需要改变任何东西。方便的HibernateTemplate公用组件使访问数据库变成小菜一碟,而DAO接口只有通过这个组件才可以访问到数据库。下面是一个示例的DAO: public class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO { public Product getProduct(Integer productId) { return (Product)getHibernateTemplate().load(Product.class, productId); } public Integer saveProduct(Product product) { return (Integer) getHibernateTemplate().save(product); } public void updateProduct(Product product) { getHibernateTemplate().update(product); } } 在业务逻辑层中使用延迟加载即使在视图外面,Spring框架也通过使用AOP 拦截器 HibernateInterceptor来使得延迟加载变得很容易实现。这个Hibernate 拦截器透明地将调用配置在Spring应用程序上下文中的业务对象中方法的请求拦截下来,在调用方法之前打开一个Hibernate会话,然后在方法执行完之后将会话关闭。让我们来看一个简单的例子,假设我们有一个接口BussinessObject: public interface BusinessObject { public void doSomethingThatInvolvesDaos(); } 类BusinessObjectImpl实现了BusinessObject接口: public class BusinessObjectImpl implements BusinessObject { public void doSomethingThatInvolvesDaos() { // lots of logic that calls // DAO classes Which access // data objects lazily } } 通过在Spring应用程序上下文中的一些配置,我们可以让将调用BusinessObject的方法拦截下来,再令它的方法支持延迟加载。看看下面的一个程序片段: com.acompany.BusinessObject hibernateInterceptor 当businessObject被调用的时候,HibernateInterceptor打开一个Hibernate会话,并将调用请求传递给BusinessObjectImpl对象。当 BusinessObjectImpl执行完成后,HibernateInterceptor透明地关闭了会话。应用层的代码不用了解任何持久层逻辑,还是实现了延迟加载。在单元测试中测试延迟加载最后,我们需要用J-Unit来测试我们的延迟加载程序。我们可以轻易地通过重写TestCase类中的setUp和tearDown方法来实现这个要求。我比较喜欢用这个方便的抽象类作为我所有测试类的基类。 public abstract class MyLazyTestCase extends TestCase { private SessionFactory sessionFactory; private Session session; public void setUp() throws Exception { super.setUp(); SessionFactory sessionFactory = (SessionFactory) getBean("sessionFactory"); session = SessionFactoryUtils.getSession(sessionFactory, true); Session s = sessionFactory.openSession(); TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s)); } protected Object getBean(String beanName) { //Code to get objects from Spring application context } public void tearDown() throws Exception { super.tearDown(); SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory); Session s = holder.getSession(); s.flush(); TransactionSynchronizationManager.unbindResource(sessionFactory); SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory); } } 我们首先说利用lazy=false来解决问题,这种方法是很好用,但是在实际的过程并不实用,如果你某个对象关联好几个甚至十几个自对象,那么每次加载一个的话要执行很多HQL语句,可想而知这个效率问题啦,特别是在使用列表的时候。所以不实用,而在上述所说的“在业务逻辑层中使用延迟加载” 也是这种情况吧。很多使用WEB的朋友都喜欢利用openSessionView来加载这个问题。不错我也喜欢用,简单方便。但是说几种情况: 1.在quartz中总不能使用openSessionView模式吧 2.在spring后拦截的过程中,如果取拦截对象中的子对象利用openSessionView也不行

解决方案:如果是在one的一方查询many,在one的一方的set方法里加入属性:lazy="false";

如果是在many的一方查询one,在many的一方的many-to-one里加上lazy="false";

 

Nsight Compute内存图表实战:如何快速定位CUDA内核的内存瓶颈(附配置截图) 本文详细介绍了如何使用Nsight Compute的Memory Chart功能快速定位和诊断CUDA内核中的内存性能瓶颈。通过解析内存图表中的逻辑与物理单元节点、连线颜色含义,并结合实战案例(如低L1缓存命中率、共享内存Bank冲突、全局内存访问未合并),指导开发者从可视化数据回溯至源代码,进行精准有效的内存访问优化,从而提升GPU程序性能。 阅读详情

相关推荐

Labview邪修01:贪吃蛇小游戏

摘要:博主使用LabVIEW 2020(32位)复刻了经典贪吃蛇游戏。程序具备随机生成蛇(初始长度3)和食物、三档速度调节、键盘方向控制等功能,碰撞边界或自身即游戏结束。实现过程包括:1)界面设计,使用二维颜色盒数组构建游戏区,添加速度枚举控件和功能按钮;2)程序架构,采用模块化设计包含Main.vi、Start.vi等6个核心VI,分别处理初始化、位置计算、碰撞检测等逻辑;3)事件驱动机制,通过开始/结束事件、按键响应和超时循环实现游戏流程控制。运行时可实时显示分数,完整还原了贪吃蛇的核心玩法。

weixin_38637405的博客 924

Hibernate 延迟加载

使⽤延迟加载可以提⾼程序的运⾏效率,Java 程序与数据库交互的频次越低,程序运⾏的效率就越⾼, 所以我们应该尽量减少 Java 程序与数据库的交互次数,Hibernate 延迟加载就很好的做到了这⼀点。客户和订单,当我们查询客户对象时,因为有级联设置,所以会将对应的订单信息⼀并查询出来,这样 就需要发送两条 SQL 语句,分别查询客户信息和订单信息。延迟加载的思路是:当我们查询客户的时候,如果没有访问订单数据,只发送⼀条 SQL 语句查询客户信 息,如果需要访问订单数据,则发送两条 SQLL。

weixin_57558097的博客 715

hibernate延迟加载解决

hibernate延迟加载解决

hibernate延迟加载

hibernate延迟加载   Hibernate对象关系映射提供延迟的与非延迟的对象初始化。非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来。这有时会导致成百的(如果不是成千的话)select语句在读取对象的时候执行。这个问题有时

bf90599188的专栏 416

Hibernate是如何延迟加载

所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。 延迟加载,可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。 延迟加载的有效期是在session打开的情况下,当session关闭后,会报异常。当调用load方法加载对象时,返回代理对象,等到真正用到对象的内容时才发出sql语句。 Hibernate2实现延迟加载有2种方式:1.实体对象 2

WangPing1223的博客 666

Hibernate延迟加载机制

 延迟加载:  延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。下面我们就分别介绍这些种类的延迟加载的细节。A、实体对象的延迟加载: 如果想对实体对象使用延迟加载,必须要在实体的映射配置文件中

javacoffe的专栏 1727

Hibernate延迟加载

hibernate中,延迟加载大致可以分为两类,一类是延迟属性加载,另一类是延迟关联实体加载。 普通属性:分两种情况,一种是集合属性,一种是非集合属性(如String、Integer......) 集合属性的延迟加载通过PersistentSet、 PersistentList、PersistentBag、PersistentMap、PersistentSortedMap、Persistent

r91987的专栏 6139

hibernate 延迟加载

Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载hibernate通过这种延迟加载来降低系统的内存开销,从而保证 Hibernate 的运行性能。 下面先来剖析 Hibernate 延迟加载的“秘密”。 集合属性的延迟加载Hibernate数据库中初始化某个持久化实体时,该实体的集合属性是否随持久化类...

126

Hibernate集合属性的延迟加载

Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载Hibernate 通过这种延迟加载来降低系统的内存开销,从而保证 Hibernate 的运行性能。 下面先来剖析 Hibernate 延迟加载的“秘密”。 集合属性的延迟加载Hibernate数据库中初始化某个持久化实体时,该实体的集合属性是否随持久化类一起初始化

jun0052的专栏 759

Hibernate 类的延迟加载 集合的延迟加载 单端的延迟加载

hibernate延迟加载有以下三种: 类的延迟加载: get方法没有延迟加载 load方法默认有延迟加载。可以在配置文件中进行配置 使用lacy是否启用延迟加载延迟加载必须在同一个session中。session关闭了就不会有延迟加载。 集合的延迟加载: 通常是在一对多和多对多关系中使用。 使用load方法的时候会有延迟加载但是还是受到 ...

Java修炼者的博客 141

hibernate延迟加载(懒加载)详解

延迟加载 一.什么是懒加载?他的作用? 延迟加载,也叫懒加载,它是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。 Hibernate中主要是通过代理(proxy)机制来实现延迟加载。它的具体过程:Hibernate数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据,hiber

张晓丛的专栏 1万+

Hibernate延迟加载

延迟加载:是在真实需要数据才执行SQL语句进行查询,避免无谓的性能开销。    类级可选:立即检索,延迟检索,默认为延迟检索                      立即检索:立即加载对指定的对象,立即发送SQL                      延迟检索:延迟加载指定检索的属性,才发送SQL    无论元素的lazy的属性是true或false , session的get( )

qq_36074150的博客 354

Hibernate延迟加载及关联关系的查询策略

【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】 为什么hibernate需要延迟加载? 通过关联关系可以在程序中方便地获取关联对象的数据,但是如果从数据库中加载Student对象时,就同时自动加载所有关联的Grade对象,而程序实际上仅仅需要访问Student对象时,那么这些关联的Grade对象就白白浪费了许多内存空间。Hibernate查询Student对象时,立即查...

q_1092535160的博客 448

Hibernate(18)Hibernate延迟加载是什么?

Hibernate延迟加载(Lazy Loading)是一种性能优化技术,仅在需要时加载关联数据,减少初始查询和内存消耗。本文通过完整示例演示了延迟加载的实现方式,包括: 配置hibernate.cfg.xml文件 创建HibernateUtil工具类 定义Student和Course实体类,使用@OneToMany和@ManyToOne注解设置延迟加载策略 示例代码展示如何在实际操作中处理延迟加载的数据 关键点:通过fetch = FetchType.LAZY设置延迟加载策略,在会话关闭前访问关联数据以避

qq_43012298的博客 457

Hibernate之lazy延迟加载

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34138139的博客 252

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

【转载按】 一篇对HIBERNATE延迟加载的内部机制分析得比较清晰的文章。 【原文】 http://www.ibm.com/developerworks/cn/java/j-lo-hibernatelazy/ Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载Hibernate 通过这种延迟加

技术拾遗 631

Buildroot架构解析

這篇文章會以『free-electrons』官網上的資料,來研究buildroot的架構並且撰寫一篇簡單的教學文,成果會從buildroot專案中建置出「bootloader」, 「kernel」和「root fileSystem」。本篇主要將會把buildroot的知識和架構在好好的解釋清楚,算是buildroot的補強。

上一篇: Load和get方法的区别
ping159
博客等级 码龄15年 6粉丝 64原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值