Hibernate 半深入懒加载与懒加载代理类
来源:互联网 发布:阿里弹性云 编辑:程序博客网 时间:2024/05/29 03:58
标签(空格分隔): 后端技术学习
前言
在hibernate的使用中,为了减少对数据库的访问,对于存在关联关系映射表使用的时候,我们可以使用懒加载的方式,让hibernate帮我查询单个对象信息的同时,暂缓查询它所关联的另一些对象的信息,当我们真正的使用它所管理的对象的时候后再帮我们查询关联对象。同时懒加载的方式也是hibernate为我们默认选择的方式。虽然懒加载为我们带来了减少数据库查询的好处,但是在使用的过程中如果是对hibernate理解不够容易出现难以寻找的问题。
引入
在课堂上老师引导我们,了解hibernate的查询方式的时候,介绍了使用懒加载的时候session.load()查询会返回的内容并不是我们真正的POJO实体对象,实际上返回的是实体对象的代理类。它跟能够在我调用POJO的getXX()方法的时候使用代理的方式帮我们进行数据库的查询实现懒加载,然后返回我们需要查寻得关联对象。接下来我们细细理解一下半深入懒加载与懒加载代理类。
session.load()讲解
API指出 session.load()
查询总是返回一个并非直接对应数据库行的假对象(代理类)。查出来的假对象它所有的属性也没有被正式的初始化。对它所有的操作,直到事务提交时才进行对它之前所有操作的合并,然后执行数据库语句。
同时在事务提交的时候,如果数据库中原本并没有假对象对应的行则会抛出ObjectNotFoundException
。
如果是没有使用事务load()查询,则在进行session.save(“假对象”),session.saveOrUpdate(“假对象”)的时候则会提示org.hibernate.PersistentObjectException: uninitialized proxy passed to save()
的异常。原因仍然假对象(代理类)懒加载。
例如 session.load()
coderInput
Stock stock = (Stock)session.load(Stock.class, new Integer(2)); StockTransaction stockTransactions = new StockTransaction(); //set stockTransactions detail stockTransactions.setStock(stock); session.save(stockTransactions);
Output
Hibernate:insert into mkyong.stock_transaction (...)values (?, ?, ?, ?, ?, ?)
注意:实际上并不是
session.load()
的所有查询都返回的是POJO实体对象的代理类,只有在POJO对象的映射文件*.hbm.xml中指定了懒加载(即没有设置lazy="false"
)的时候才会返回POJO实体对象的代理类。否则不是代理类。
session.get讲解
相对于session.load()
,session.get()
就非常直接,使用它的每一次查询操作返回的都是对应着数据库中的真实对象,这个对象代表的是数据库中真实的一行,也不是代理类。
真是因为这个原因session.get()
的查询它是不支持懒加载的。如果查询的类有关联对象,它会同时将关联对象统统查出来。
如果在数据库的查询中找不到对应搜索条件的行则返回null,通过由于在session.get()
返回的不是代理类,在session.close()
后它不会被销毁,不会为空。
例如 session.get()
codeInput
Stock stock = (Stock)session.get(Stock.class, new Integer(2)); StockTransaction stockTransactions = new StockTransaction(); //set stockTransactions detail stockTransactions.setStock(stock); session.save(stockTransactions);
Output
Hibernate:select ... from mkyong.stock stock0_where stock0_.STOCK_ID=?Hibernate:insert into mkyong.stock_transaction (...)values (?, ?, ?, ?, ?, ?)
代理类
代理类是通过动态代理的方式创建,是由Hibernate框架帮我们创建的,这也是Hibernate框架的面相切面的特点。Hibernate在通过*.hbm.xml文件帮我们让数据库和正真实体之间建立联系,同时又为我们提供了关联关系映射的功能。在使用懒加载模式下的时候使用session.load
等查询的时候,会返回给我们一个代理类。代理类的所有属性都会在真正使用的时候才会去加载。如果仅仅只是执行了查询语句,没有任何的修改访问操作,实际上最后的事务提交时Hibernate是没有进行数据库查询的。
同时非常重要的一点是Hibernate的会在代理类相关联session关闭的时候,会同时销毁代理类。也就是说如果你所使用的引用是代理类,你执行了session.close()
,你再去访问这个代理类就会的到这样的org.hibernate.LazyInitializationException: could not initialize proxy - no Session
报错提示。
但是如果是使用的session.get(),或者是关闭了懒加载则不会使用到代理类,不会出现上述问题。同时也享受不到Hibernate智能的数据库优化。
- Hibernate 半深入懒加载与懒加载代理类
- hibernate 懒加载时的代理类
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate懒加载深入分析
- Hibernate深入之get()与load()懒加载
- Hibernate深入之get()与load()懒加载
- hibernate的懒加载代理模式
- hibernate代理实现懒加载+cglib和jdk动态代理
- hibernate 延迟加载与动态代理
- hibernate 懒加载、延时加载
- 代理和懒加载
- poj 2886
- 通过setxxx()和getxxx()方法对类中的私有成员变量进行赋值和访问
- JavaScript的typeof运算符的可能结果
- 【C++心路历程41】【体检】【贪心】【思路题】
- linux命令--tree显示文件目录结构
- Hibernate 半深入懒加载与懒加载代理类
- NOIP2016 换教室 期望DP
- 谷歌的天敌竟然是亚马逊?从开放 7-Mic 阵列授权说起 | 洞见
- 95后中专肄业生登上欧洲顶级安全会议舞台
- JavaWeb学习心得之JSP内置对象
- JS中的this关键字
- kotlin
- Boundary-Aware Fully Convolutional Network for Brain Tumor Segmentation论文理解
- redis打开外网访问端口