hibernate--lazy(懒加载)属性

2023-11-04

关联映射文件中<class>标签中的lazy(懒加载)属性

Lazy(懒加载):只有在正真使用该对象时,才会创建这个对象

Hibernate中的lazy(懒加载):只有我们在正真使用时,它才会发出SQL语句,给我们去查询,如果不使用对象则不会发SQL语句进行查询。

Hibernate中lazy(懒加载)的实现:

采用了第三方组件的库,这个库叫cglib.jar(比较流行),这个库对我们的类生成代理类(JDK的动态代理,只能对JDK中实现了接口的类进行代理),代理可以控制源对象并且可以对源对象的功能进行增强,而cglib.jar可以对类进行代理(cglib对我们的类进行继承,生成一个子类,这个子类作为代理类返回给你)。

只有你正真代理类的方法,则会查看你有没有加载目标对象,如果没有则会加载目标对象。

Lazy(懒加载)在hibernate何处使用:

1、<class>标签上,可以取值:true/false,(默认值为:true)

2、<property>标签上,可以取值:true/false,需要类增强工具

3、<set>、<list>集合上,可以取值:true/false/extra,(默认值为:true)

4、<one-to-one>、<many-to-one>单端关联上,可以取值:false/proxy/noproxy

Session.load()方法支持lazy,而session.get()不支持lazy;

Hibernate的lazy生效期:

生效期和session一样的,session关闭,lazy失效

hibernate支持lazy策略只有在session打开状态下有效。

<class>标签上,可以取值:true/false,(默认值为:true):

实例一:设置<class标签上的lazy=true(默认)

@Test
    public void LazyTest() {
        session = HibernateUtil.getSession();
        tx = session.beginTransaction();

        // 执行此语并不会发SQL语句,只是返回一个代理类
        Group group = (Group) session.load(Group.class, 1);

        // 不会发SQL语句,使用上面输入的1值
        System.out.println("group.id=" + group.getId());

        // 此处使用对象,会发出SQL语句
        System.out.println("group.name=" + group.getName());

        // 提交事务
        tx.commit();
    }

输出:

group.id=1
Hibernate: select group0_.id as id1_1_0_, group0_.name as name2_1_0_ from t_group group0_ where group0_.id=?

设置<class标签上的lazy=true(默认)

@Test
    public void LazyTest1(){
        Session session = null;
        Transaction tx = null;
        Group group = null;
            
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
    
            group =(Group)session.load(Group.class, 1);
            
            System.out.println("group.name=" + group.getName());
            
            //提交事务
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession(session);
        }
        
        //不能正确输出,抛出了LazyInitalizationException异常,因为session已经关闭
        //hibernate支持lazy策略只有在session打开状态下有效。
        System.out.println("group.name=" + group.getName());
    }

关联映射文件中集合标签中的lazy(懒加载)属性

<set>、<list>集合上,可以取值:true/false/extra,(默认值为:true)

实例一:(集合上的lazy=true(默认))

@Test
    public void LazyTest2() {

        session = HibernateUtil.getSession();
        tx = session.beginTransaction();
        // 不会发出SQL语句
        Classes classes = (Classes) session.load(Classes.class, 1);
        // 发出SQL语句,因为在使用对象
        System.out.println("classes.name=" + classes.getName());

        // 不会发SQL语句,只会返回一个代理类,因为没有使用对象
        Set<Student> students = classes.getStudents();

        // 会发出SQL语句,因为使用了对象
        for (Iterator<Student> iter = students.iterator(); iter.hasNext();) {
            Student student = iter.next();
            System.out.println(student.getName());
        }

        // 提交事务
        tx.commit();
    }

实例二:集合上的lazy=true(默认)

session = HibernateUtils.getSession();
            tx = session.beginTransaction();
    
            //不会发出SQL语句
            Classes classes = (Classes)session.load(Classes.class, 1);
            //发出SQL语句,因为在使用对象
            System.out.println("classes.name=" + classes.getName());
            
            //不会发SQL语句,只会返回一个代理类,因为没有使用对象
            Set<Student> students = classes.getStudents();
            
            //会发出SQL语句,发出查询全部数据的SQL,效率不高
            System.out.println("student.count=" + students.size());
            
            //提交事务
            tx.commit();

实例三:集合上的lazy=false,其它保持默认

//不会发出SQL语句,因为只设置了集合上的lazy为false,其它保持默认
            Classes classes = (Classes)session.load(Classes.class, 1);
            //发出两条SQL语句,分别加载classes和student
            //并且把集合中的数据也加载上来(虽然并没有使用集合中的对象),因为设置了集合的lazy=false
            System.out.println("classes.name=" + classes.getName());
            
            //不会发SQL语句,因为已经在前面加载了数据
            Set<Student> students = classes.getStudents();
            
            //会发出SQL语句,因为已经在前面加载了数据
            for (Iterator<Student> iter = students.iterator();iter.hasNext();){
                Student student = iter.next();
                System.out.println(student.getName());
            }

实例四:集合上的lazy=false,其它保持默认

//不会发出SQL语句
        Classes classes = (Classes)session.load(Classes.class, 1);
        //发出两条SQL语句,分别加载classes和student
        //并且把集合中的数据也加载上来(虽然并没有使用集合中的对象),因为设置了集合的lazy=false
        System.out.println("classes.name=" + classes.getName());
        
        //不会发SQL语句,因为已经在前面加载了数据
        Set<Student> students = classes.getStudents();
        
        //不会发SQL语句,因为已经在前面加载了数据
        System.out.println("student.count=" + students.size());

实例五:设置集合上lazy=extra,其它默认

session = HibernateUtils.getSession();
            tx = session.beginTransaction();
    
            //不会发出SQL语句
            Classes classes = (Classes)session.load(Classes.class, 1);

            //会发出SQL语句
            System.out.println("classes.name=" + classes.getName());
            
            //不会发出SQL语句,只返回代理类
            Set<Student> students = classes.getStudents();
            
            //会发出SQL语句
            for (Iterator<Student> iter = students.iterator();iter.hasNext();){
                Student student = iter.next();
                System.out.println(student.getName());
            }

实例六:设置集合上lazy=extra,其它默认

session = HibernateUtils.getSession();
        tx = session.beginTransaction();

        //不会发出SQL语句
        Classes classes = (Classes)session.load(Classes.class, 1);
        //发出两条SQL语句
        System.out.println("classes.name=" + classes.getName());
        
        //不会发出SQL语句
        Set<Student> students = classes.getStudents();
        
        //发出SQL语句,发出一条比较智能的SQL语句(select count(id) form t_student where classesid=?)
        System.out.println("student.count=" + students.size());
        
        //提交事务
        tx.commit();

<one-to-one>、<many-to-one>单端关联上的lazy(懒加载)属性

Ø <one-to-one>、<many-to-one>单端关联上,可以取值:false/proxy/noproxy(false/代理/不代理)

实例一:所有lazy属性默认(支持懒加载)

session = HibernateUtils.getSession();
            tx = session.beginTransaction();

            //不发出SQL语句,支持lazy(懒加载)
            User user = (User) session.load(User.class, 3);
            //发出SQL语句,只加载普通属性,集合中的数据不会加载
            System.out.println("user.name=" + user.getName());
            
            //不会发出SQL语句,只返回代理类
            Group group = user.getGroup();
            //发出SQL语句,因为现在真正使用对象
            System.out.println("group.name=" + group.getName());
            tx.commit();

实例二:将<many-to-one>中的lazy设置为false,其它默认

session = HibernateUtils.getSession();
            tx = session.beginTransaction();

            //不会发出SQL
            User user = (User) session.load(User.class, 3);
            //会发出SQL,发出两条SQL,分别是User和组
            //因为<many-to-one>中的lazy=false,则会加载Group
            System.out.println("user.name=" + user.getName());
            
            //不会发出,已经在上面加载了数据
            Group group = user.getGroup();
            //不会发出,已经在上面加载了数据
            System.out.println("group.name=" + group.getName());
            tx.commit();

实例三:将<class>中的lazy设置为false,其它默认

session = HibernateUtils.getSession();
            tx = session.beginTransaction();

            //会发出SQL,因为<class>中的lazy=false
            User user = (User) session.load(User.class, 3);
            //不会发出SQL,已经在上面加载了
            System.out.println("user.name=" + user.getName());
            
            //不会发出,因为<class>标签上的lazy只对普通属性的影响
            //<class>标签上的lazy不会影响到单端关联上的lazy特性
            Group group = user.getGroup();
            //会发出,因为开始使用对象
            System.out.println("group.name=" + group.getName());

            tx.commit();

转载于:https://www.cnblogs.com/sunhan/p/3823372.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

hibernate--lazy(懒加载)属性 的相关文章

随机推荐

  • SetupDiGetDeviceInterfaceDetail

    SetupDiGetDeviceInterfaceDetail 该函数返回设备接口的详细信息 BOOL SetupDiGetDeviceInterfaceDetail In HDEVINFO DeviceInfoSet In PSP DEV
  • STM32定时器系列 - STM32常规定时器时基与时钟源

    常规定时器包括 基本定时器 通用定时器和高级定时器 基本定时器 没有任何对外输入 输出 主要用作时基计数 定时 通用定时器 除了基本定时器的时基功能外 还可对外做输入捕捉 输出比较以及连接其它传感器接口 编码器和霍尔传感器 高级定时器 此类
  • C语言深入理解指针(非常详细)(一)

    目录 内存和地址 内存 编址的理解 指针变量和地址 取地址操作符 指针变量和解引用操作符 指针变量 如何拆解指针类型 解引用操作符 指针变量的大小 指针变量类型的意义 指针的解引用 指针 整数 const修饰指针 const修饰变量 con
  • 【Mybatis】Mybatis插入中文乱码问题

    1 首先看数据库中和idea中是否都是utf 8编码 1 数据库 新建查询 gt 输入 SHOW FULL COLUMNS FROM 数据库名 表名 查看所有字段编码 2 IDEA 点击File Settings Editor File E
  • 后端开发学习Vue(一)

    Vue的介绍 官网 https cn vuejs org Vue是一个简单容易上手前端框架 例如 下面的代码可以快速构建一个表格
  • rpy2库

    在数据分析中 Python和R各有千秋 虽然Python或R都能在数据分析打通关 从采集 清洗 预处理 分析 可视化 但是在不同的环节 不同的语言易用程度不同 Python胜在干脏活累活 诸如数据采集 数据清洗 机器学习等 而R语言胜在统计
  • 【机器学习】聚类【Ⅰ】基础知识与距离度量

    主要来自周志华 机器学习 一书 数学推导主要来自简书博主 形式运算 的原创博客 包含自己的理解 有任何的书写错误 排版错误 概念错误等 希望大家包含指正 由于字数限制 分成五篇博客 机器学习 聚类 基础知识与距离度量 机器学习 聚类 原型聚
  • 用c语言打印九九乘法表

    分析 这是一个典型的使用循环嵌套的题目 把题目分成两部分 被乘数和乘数 被乘数的变化是从1变化到9 乘数的变化是根据被乘数而来 这样就决定了被乘数的变化做为外循环 乘数的变化作为内循环 1 1 1 2 1 2 2 2 4 3 1 3 3 2
  • 路径遍历(目录遍历)

    一 简介 路径遍历攻击也称为目录遍历 旨在 访问存储在web根文件夹之外的文件和目录 通过操纵带有 点 斜线 序列及其变化的文件或使用绝对路径来引用文件的变量 来访问存储在文件系统上的任意文件和目录 包括应用程序源代码 配置和关键系统文件
  • 中国移动光猫无线路由一体机如何再接另外一个无线路由器

    将无线路由器连接光猫 用一条网线一端接入光猫网口1或网口3或网口4 另一端接入无线路由器WAN接口 将无线路由器连接电脑 用一条网线一端接入无线路器LAN接口 另一端插入电脑 光猫的默认地址为192 168 1 1 所以无线路由器的LAN口
  • 日期加年,返回年份

    日期加年 返回字符串 param date str yyyy mm dd 必须是这个格式 param year 加的年 return string 年份 static function dateAddYear date str year i
  • 数据库连接异常:create connection error, url: jdbc:mysql://ip/数据库名, errorCode 0, state 08S01问题处理

    今天项目中新增了一部分接口 本地测试好之后打包部署到测试环境 数据库竟然连接失败 报错信息如下 create connection error url jdbc mysql ip 数据库名 errorCode 0 state 08S01 这
  • solidworks齿轮编辑_如何应用solidworks进行齿轮工程图绘制

    引言 齿轮是一种常用的传动零件 也是机械设计过程中经常需要设计的一种零件 由于齿轮的工程图绘制与一般零件有较大区别 在利用一般的三维软件设计出三维图形后并不能马上得到准确的二维图形 这种情况会大大降低工程技术人员的设计速度 增加设计成本 S
  • 安卓数据线ssh连树莓派(超简单)

    无需联网 无需无限网卡 树莓派 sudo vim etc network interfaces 添加或修改这句iface usb0 inet dhcp 然后手机数据线插上树莓派 开启usb网络共享 用better terminal或者ter
  • 记录一个std::future和std::async的demo

    Demo和代码简述 子线程函数 参数a传进去模拟遇到的带参数问题 函数的返回值可以是处理完的任意值 若有返回值则get 到的就是返回值 比如这个demo里get到的就是3 int TestNoClass int a int main int
  • LFSR

    c语言中实现LFSR define CRT SECURE NO WARNINGS include
  • 同步式SPWM两电平正弦脉宽调制逆变器(全波三角波)——正弦波为调制波(双重傅里叶分析)

    SPWM正弦脉宽调制介绍 SPWM是调制波为正弦波 载波为三角波或锯齿波的一种脉宽调制法 特点 原理简单 通用性强 控制和调节性能好 具有先出谐波 调节和稳定输出电压的多种作用 是一种比较好的波形改善法 分类 分为两阶式和三阶式两种 阶 指
  • S3C2440读写sd卡的一些总结

    整理硬盘的时候发现这个文档 以前写2440操作sd卡程序的时候总结的 1 我的2440 sdi对sd卡发送ACMD41时总是反馈crc fail 但是可以得到正确的response sd卡可以正常使用 2 sd卡可以没有mbr 在物理的 0
  • 推理规则的具体应用

    小伙伴们 大家好呀 相信步入大二的同学们肯定会学到离散数学 而推理规则是离散数学中最fundmental and important 的知识体系 今天我们来说说基本的推理规则 Firstly 推理 inference rules 是 前提
  • hibernate--lazy(懒加载)属性

    关联映射文件中