Hibernate学习笔记-懒加载Lazy-true

1. 懒加载概述以及使用情景

描述:懒加载(lazy),简单说就是延时、延迟加载。

情景:在Hibernate框架应用中,就是当我们要访问的数据量过大时,使用缓存并不太合适,因为内存容量有限 ,为了减少系统资源的消耗,减少并发量,这时需要用懒加载机制来弥补这种缺陷,但是这并不意味用了懒加载总体性能就提高了。

应用:

比如学校school和学生student,学校与学生1对多,如果lazy设置为 false,那么只要加载了一个学校的信息,就会根据一对多配置的关系把所有学生的信息也加载出来。但是实际上有时候只是需要用到学校的信息,不需要用到 学生的信息,这时学生信息的加载就等于浪费资源。如果lazy设置为true,那么只有当你访问学校信息的学生信息时候才会去加载学生的信息的信息。

2. 懒加载的原理

在Hibernate中运用session进行查询时,有get()和load()两个方法,先说一下两者的区别:

这两种方法的不同就是load()拥有懒加载的特性。Load()方法就是在查询某一条数据的时候并不会直接将这条数据以指定对象的形式来返回,而是在你真正需要使用该对象里面的一些属性的时候才会去数据库访问并得到数据。他的好处就是可以减少程序本身因为与数据库频繁的交互造成的处理速度缓慢。

* session.get()

* 1、方法加载出来的对象是class对象

* 2、在session.get方法执行的时候发出sql语句

* 3、class对象是有值的

* session.load ()

* 1、方法加载出来的对象是class的代理对象

* 2、在加载其属性的时候发出sql语句(按照需求加载,延迟加载)

* 3、获取标识符(UUID)属性是不用延迟加载的,获取普通属性是需要发出sql语句的

在此以User类为例

    public static void query(int id){
           Session session=null;
            try{
                session=HibernateUtil.getSession();
                User user=(User) session.load(User.class, id);
                //System.out.println(user.getName());
                System.out.println(user.getClass());
            }catch(HibernateExceptionex){
                ex.printStackTrace();
            }finally{
                if(session!=null){
                   session.close();
                }
            }
    }

运行上述方法后,我们并没有看到Hibernate打印任何查询语句,当将注释的语句打开,可以查询到的User的name。这时我们可以看到Hibernate产生的查询语句并看到user的name属性。这就是懒加载了。

3.懒加载代理对象

通过打印user.getClass()方法来验证,打印出来的结果并不是null,其实是代理对象,而这个对象所属的类是User类的子类,是Hibernate自动实现的一个子类。

代理对象的生命周期是什么呢?

    public static User query(int id){
           Session session=null;
           User User=null;
            try{
                session=HibernateUtil.getSession();
                User=(User)session.load(User.class, id);
                //System.out.println(User.getName());
            }catch(HibernateExceptionex){
                ex.printStackTrace();
            }finally{
                if(session!=null){
                   session.close();
                }
            }
            return User;
        }

//会抛出一个org.hibernate.LazyInitializationException异常

这说明懒加载的时候如果想通过代理对象查询数据库,需要在该session关闭以前才可以。但如果一定要在session关闭以后再使用代理对象的话,Hibernate中定义了一个初始化代理对象的方法initialize(),通过该方法即可将代理对象初始化。

4. 懒加载功能实现总结

1.通过Session.load()实现懒加载

load(Object, Serializable):根据id查询 。查询返回的是代理对象,不会立刻访问数据库,是懒加载的。当真正去使用对象的时候才会访问数据库。

用load()的时候会发现不会打印出查询语句,而使用get()的时候会打印出查询语句。

使用load()时如果在session关闭之后再查询此对象,会报异常:could not initialize proxy - no Session。处理办法:在session关闭之前初始化一下查询出来的对象:Hibernate.initialize(user);

使用load()可以提高效率,因为刚开始的时候并没有查询数据库。但很少使用。

2.one-to-one(元素)实现了懒加载。

在一对一的时候,查询主对象时默认不是懒加载。即:查询主对象的时候也会把从对象查询出来。

需要把主对象配制成lazy=”true” constrained=”true” fetch=”select”。此时查询主对象的时候就不会查询从对象,从而实现了懒加载。

一对一的时候,查询从对象的是默认是懒加载。即:查询从对象的时候不会把主对象查询出来。而是查询出来的是主对象的代理对象。

3.many-to-one(元素)实现了懒加载。

多对一的时候,查询主对象时默认是懒加载。即:查询主对象的时候不会把从对象查询出来。

多对一的时候,查询从对象时默认是懒加载。即:查询从对象的时候不会把主对象查询出来。

hibernate3.0中lazy有三个值,true,false,proxy,默认的是lazy=”proxy”.具体设置成什么要看你的需求,并不是说哪个设置就是最好的。在与标签上:当为true时,会有懒加载特性,当为false时会产生N+1问题,比如一个学生对应一个班级,用一条SQL查出10个学生,当访问学生的班级属性时Hibernate会再产生10条SQL分别查出每个学生对应的班级.

lazy= 什么时候捉取

fetch= 捉取方式:select=关联查询;join=连接表的方式查询(效率高)

fetch=join时,lazy的设置将没有意义.

4. one-to-many(元素)懒加载:默认会懒加载,这是必须的,是重常用的。

一对多的时候,查询主对象时默认是懒加载。即:查询主对象的时候不会把从对象查询出来。

一对多的时候,查询从对象时默认是懒加载。即:查询从对象的时候不会把主对象查询出来。

需要配置主对象中的set集合lazy=”false” 这样就配置成是不懒加载了。或者配置抓取方式fetch=”join”也可以变成不懒加载。

时间: 2024-12-23 20:05:44

Hibernate学习笔记-懒加载Lazy-true的相关文章

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

Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载.Hibernate 通过这种延迟加载来降低系统的内存开销,从而保证 Hibernate 的运行性能. 下面先来剖析 Hibernate 延迟加载的"秘密". 集合属性的延迟加载 当 Hibernate 从数据库中初始化某个持久化实体时,该实体的集合属性是否随持久化类一起初始化呢?如果集合属性里包含十万,甚至百万的记录,在初始化持久化实体的同时, 完成所有集合属性的抓取,

解决hibernate中的懒加载(延迟加载)问题

解决hibernate中的懒加载(延迟加载)问题 我们在开发的时候经常会遇到延迟加载问题,在实体映射时,多对一和多对多中,多的一样的属性默认是lazy="true"(即,默认是延迟加载), 如:<many-to-one name="parent" class="Department" column="parentId" lazy="true"/> 延迟加载表现在:比如:我们要查询id为2的部门数

OGEngine学习笔记---资源加载

声音管理兼容各种音频文件格式,比特率和样本率 OGEngine开源引擎兼容各种音频视频文件格式,并且引用了硬件加速技术,来对音频文件进行io读取,简化了资源的加载和读取写入的过程,大幅度减少应用卡顿.无响应的状况出现. 一个背景音乐 多个音效 OGEngine开源引擎在同一时间只能播放一首背景音乐,但是能同时播放多个音效. 首先自定义一个枚举类ConfigData,用来存放背景音乐key和音效key. public class ConfigData { /** 背景音乐*/ public sta

iOS 开发——实用技术Swift篇&amp;Swift 懒加载(lazy)

Swift 懒加载(lazy) 在程序设计中,我们经常会使用 * 懒加载 * ,顾名思义,就是用到的时候再开辟空间,比如iOS开发中的最常用控件UITableView,实现数据源方法的时候,通常我们都会这样写 Objective-C 1 //必须实现的数据源代理方法 2 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 3 { 4 return self.dataArr

Swift中懒加载(lazy initialization)的实现

Swift中是存在和OC一样的懒加载机制的,但是这方面国内的资料比较少,今天把搜索引擎换成了Bing后发现用Bing查英文\最新资料要比百度强上不少. 我们在OC中一般是这样实现懒加载初始化的: 1: @property (nonatomic, strong) NSMutableArray *players; 2:   3: - (NSMutableArray *)players { 4: if (!_players) { 5: _players = [[NSMutableArray alloc

Away3D 学习笔记(一): 加载3DS格式的模型文件

加载外部的3DS文件分为两种: 1: 模型与贴图独立于程序的,也就是从外部的文件夹中读取 1 private function load3DSFile():Loader3D 2 { 3 loader = new Loader3D(); 4 loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE,onLoadComplete); 5 loader.addEventListener(AssetEvent.ASSET_COMPLETE,onAsset

Swift学习(4懒加载、计算型属性、反射机制)

懒加载.计算型属性.反射机制 1.懒加载: 目的:1.延迟创建,需要时加载,节省内存空间 2.避免开发中处理解包的问题(重要!!!) 知识:1.所有的UIView 及子类在开发是,一旦重写了够着函数,必须要实现initwithcoder函数以保证提供两个通道,目前Xcode会有提示. 2.在swift中懒加载的简单写法 lazy var label:UILabel = UILabel() 3.懒加载本质上是一个闭包,完整写法如下: {}包装代码  ()执行代码 lazy var labe = {

20.Swift懒加载lazy

// Swift懒加载使用lazy关键字来修饰属性 // 在属性后面跟= {}进行具体的赋值 // 只会被加载一次 lazy var names : [String]? = { // () -> ([String]) in print("加载数据") return ["why", "lnj", "lmj"] }() override func viewDidLoad() { super.viewDidLoad() } o

Swift 懒加载(lazy) 和 Objective-C 懒加载的区别

在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间,比如iOS开发中的最常用控件UITableView,实现数据源方法的时候,通常我们都会这样写 Objective-C - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataArray.count; } - (UITableViewCell *)tableView: