4.0、Hibernate-延迟加载 2

news2024/11/23 22:02:36

4.0、Hibernate-延迟加载 2

        消费者 和 订单 属于 一对多 的 关系,通过上一章节 3.0 的内容我们知道了可以通过设置 customer 来实现延迟加载,本章节来介绍一下如何设置 orders 去实现延迟加载;

        one-to-many 的 lazy 默认是 true 是开启的,先比较之下 many-to-one 默认是 false 是关闭的;

第一步:将order.hbm.xml 文件中改为 lazy = false,customer.hbm.xml 不变仍旧是 lazy = extra ->

<many-to-one name="customer" class="com.hkl.pojo.Customer" column="cid" lazy="false"></many-to-one>

第二步:创建 Test5.java 测试文件,如下所示 ->

import com.hkl.pojo.Order;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test5 {
    public static void main(String[] args) {
        //        创建configuration
        Configuration configuration = new Configuration().configure();
//        获取sessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
//        获取Session
        Session session = sessionFactory.openSession();

        Order order = session.get(Order.class,3);
        System.out.println(order);
        session.close();
    }
}

第三步:运行 Test5.java 文件,运行结果 如下所示 -> 

可以看到执行了两条 SQL 语句;

第四步:将 Order.hbm.xml 中的 lazy 设置为 proxy ->

<many-to-one name="customer" class="com.hkl.pojo.Customer" column="cid" lazy="proxy"></many-to-one>

第五步:再次运行 Test5.java,结果如下图所示->

 可以看到只有一条SQL语句了;

第六步:将Test5.java 文件中的 System.out.println(order); 改为以下语句时,再去运行 ->

System.out.println(order.getCustomer());

可以发现又变回两条SQL语句了->

那么这里再补充一下关于 proxy 和 no-proxy 的区别:

        no-proxy:当调用方法需要访问customer的成员变量时,发送 SQL 语句查询 Customer,否则不查询;

        proxy:无论调用方式是否需要访问 customer 的成员变量,都会发送 SQL 语句查询 Customer;

下面来说一下 多对多 的关系如何对操作 ->

多对多关系 课程与学生 -> 查询 课程 Course ,加载对应的 学生 Account ,默认延迟加载开启;

第一步:首先创建两个pojo实体类文件,Account.java 和 Course.java 和他们相对应的 xml 映射文件 ,如下所示->

Account.java->

package com.hkl.pojo;
import java.util.Set;

public class Account {
    private Integer id;
    private String name;
    private Set<Course> courses;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Course> getCourses() {
        return courses;
    }

    public void setCourses(Set<Course> courses) {
        this.courses = courses;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Course.java -> 

package com.hkl.pojo;
import java.util.Set;

public class Course {
    private Integer id;
    private String name;
    private Set<Account> accounts;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(Set<Account> accounts) {
        this.accounts = accounts;
    }

    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Course.hbm.xml 映射文件如下所示->

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.hkl.pojo.Course" table="t_course">
        <!--        主键映射,数据库表中的主键字段用 id 配置,而 name = "id" 这个 id 指的是 Account 实体类中的 id 属性名-->
        <id name="id" type="java.lang.Integer">
            <!--            数据库表 id 主键字段配置-->
            <column name="id"></column>
            <!--            设置主键自增方式 -> identity-->
            <generator class="identity"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <!--courses是实体类Course中的属性名,该属性是一个 Course 类的集合,所以对应表 account_course-->
        <set name="accounts" table="account_course" lazy="true">
            <!--这里配置一下主外键 aid -->
            <key column="cid"></key>
            <!--学生和选课的关系是多对多,所以这里是 many-to-many,然后给set类型加一个对象,对象类型是Course , column是course在这个中间表中的外键cid-->
            <many-to-many class="com.hkl.pojo.Account" column="aid"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

Account.hbm.xml 映射文件如下所示->

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.hkl.pojo.Account" table="t_account">
        <!--        主键映射,数据库表中的主键字段用 id 配置,而 name = "id" 这个 id 指的是 Course 实体类中的 id 属性名-->
        <id name="id" type="java.lang.Integer">
            <!--            数据库表 id 主键字段配置-->
            <column name="id"></column>
            <!--            设置主键自增方式 -> identity-->
            <generator class="identity"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <!--courses是实体类Course中的属性名,该属性是一个 Course 类的集合,所以对应表 account_course-->
        <set name="courses" table="account_course">
            <!--这里配置一下主外键 cid -->
            <key column="aid"></key>
            <!--学生和选课的关系是多对多,所以这里是 many-to-many,然后给set类型加一个对象,对象类型是Account , column是account在这个中间表中的外键aid-->
            <many-to-many class="com.hkl.pojo.Course" column="cid"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

第二步:创建测试 Test6.java 文件如下所示->

import com.hkl.pojo.Course;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test6 {

    public static void main(String[] args) {
        //        创建configuration
        Configuration configuration = new Configuration().configure();
//        获取sessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
//        获取Session
        Session session = sessionFactory.openSession();

        Course course = session.get(Course.class,1);
        System.out.println(course);
        session.close();
    }

}

运行结果如下所示 ->

 可以发现只有一条 SQL 语句;

 第三步:将 Test6.java 测试文件中的 System.out.println(course);  改为 ->

System.out.println(course.getAccounts());

再去运行,结果如下图所示 ->

 可以看到执行了三条 SQL 语句【因为 多对多 关系之间有三张表】;

这里我们先把 Course.hbm.xml 中的 lazy 设置为 false 关掉延迟加载 ->

        <set name="accounts" table="account_course" lazy="false">
            <!--这里配置一下主外键 aid -->
            <key column="cid"></key>
            <!--学生和选课的关系是多对多,所以这里是 many-to-many,然后给set类型加一个对象,对象类型是Course , column是course在这个中间表中的外键cid-->
            <many-to-many class="com.hkl.pojo.Account" column="aid"></many-to-many>
        </set>

        然后去运行 Test6.java 不管我们有没有级联操作都是执行两条 SQL 语句,而之前开启 延迟加载 之后会发现,当不涉及级联操作的时候就是一条 SQL 语句,涉及级联操作的时候才会变成两条 SQL 语句;

        那么 多对多 关系两边是都一样的,这里 Account 和 Course 相同,所以 Account 就不做演示了;

        这里和 一对多 的区别就是,当涉及级联操作的时候,一对多只需要查询两张表即可,而多对多关系中,需要三张表才能将他们两个关联起来,所以当多对多涉及级联操作的时候会执行三条 SQL 语句;如下图所示->

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/108680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

%29 身份认证

1、Web 开发模式 &#xff08;1&#xff09;、基于服务器渲染的开发模式&#xff1a;服务器发送给客户端的 HTML 页面&#xff0c;是在服务器通过字符串的拼接&#xff0c;动态生成的&#xff08;企业级网站&#xff09; &#xff08;2&#xff09;、基于前后端分离的开发模式&…

登录过程(vuex存储token、token持久化)

登录过程(vuex存储数据) 点击登录按钮通过表单校验 this.$refs.loginForm.validate(valid > {if (valid) {//按钮动画加载,禁用 this.loading true// 调用vuex的action发送登录请求this.$store.dispatch(user/login, this.loginForm).then(() > {this.$router.push({ p…

内存分配函数(动态内存分配)详解

目录 &#x1f391;为什么要进行动态内存开辟&#xff1f; &#x1f391;malloc和free &#x1f3a0;malloc函数 &#x1f3a0;free函数 &#x1f3a0;malloc函数和free函数的实际应用 &#x1f391;calloc函数 &#x1f391;realloc函数 &#x1f3a0;realloc函数的使用示例 &…

通过脚手架vue-cli创建一个vue项目

我需要在vue-demo文件下新建vue项目 步骤一 ①在该文件夹下打开集成终端 输入创建命令 命令 vue create 项目名称 &#xff0c;注意不要使用驼峰命名法 如果是第一次配置&#xff0c;有面的提示&#xff0c;这里说你这样速度会很慢的&#xff0c;用不用镜像啊&#xff0c;这…

样品制备丨艾美捷硝酸盐/亚硝酸盐荧光法检测试剂盒

一氧化氮&#xff08;NO&#xff09;是由一氧化氮合酶&#xff08;NOS&#xff09;在生物系统中合成的。NOS是一种非常复杂的酶&#xff0c;作用于分子氧、精氨酸和NADPH&#xff0c;产生NO、瓜氨酸和NADP。这个过程需要五个额外的辅因子&#xff08;FMN、FAD、血红素、钙调素和…

制造业ERP管理系统在企业采购管理中的作用是什么?

对于任何一家企业&#xff0c;采购都是头等大事。企业的采购工作往往是决定了企业产品的交货速度、成本和质量&#xff0c;特别是在制造行业&#xff0c;采购成本甚至占比产品成本的60%以上&#xff0c;降低采购成本是提高企业竞争力的关键。因此&#xff0c;对于企业采购领域的…

Effective C++条款34:区分接口继承和实现继承

Effective C条款34&#xff1a;区分接口继承和实现继承&#xff08;Differentiate between inheritance of interface and inheritance of implementation&#xff09;条款34&#xff1a;区分接口继承和实现继承1、纯虚函数2、虚函数&#xff08;非纯&#xff09;2.1 将默认实现…

2022 IoTDB Summit:中国核电刘旭嘉《工业时序数据库 Apache IoTDB 在核电的应用实践》...

12 月 3 日、4日&#xff0c;2022 Apache IoTDB 物联网生态大会在线上圆满落幕。大会上发布 Apache IoTDB 的分布式 1.0 版本&#xff0c;并分享 Apache IoTDB 实现的数据管理技术与物联网场景实践案例&#xff0c;深入探讨了 Apache IoTDB 与物联网企业如何共建活跃生态&#…

middlebury立体匹配评估使用方法总结(三)——线上版教程

系列文章目录 middlebury立体匹配评估使用方法总结&#xff08;一&#xff09;——网站说明 middlebury立体匹配评估使用方法总结&#xff08;二&#xff09;——python版离线教程 middlebury立体匹配评估使用方法总结&#xff08;三&#xff09;——线上版教程 文章目录系列文…

TableLayout布局

表格布局-TableLayout 1.TableLayout简介 1.简介 表格的形式&#xff0c;整齐可以嵌套继承于线性布局2.行数如何确定&#xff1f; tableRow&#xff0c;来指定行数列数由最多的那个决定layout_column来指定具体的列数&#xff0c;从0开始2.TableLayout的常见属性 所有的都是从0…

VMware ESxi 服务器迁移【手动版】

VMware ESxi 迁移【手动版】 应用场景 两个不同环境下的服务器进行迁移 因为不能直接对拷&#xff0c;需要在中间机上转一下 才有了这么一出 第一步 搭建NFS 在中间机上安装NFS&#xff08;或者其他磁盘挂载方式&#xff09; 目的呢是把源服务器上的系统拷贝到中间机上&#x…

android入门之broadcast

1. 前言 广播Broadcast是android四大组件之一。是用来互相通信&#xff08;传递信息&#xff09;的一种机制。 通信包括&#xff1a; a) 组件间&#xff08;应用内&#xff09;通信 b) 进程间通信 2. 广播Brocast的基本使用方式 广播发送者&#xff1a;Acvitity、Service等…

pdf文档页码怎么添加?分享这几个pdf加页码方法给你

不管是还在校园里的学生&#xff0c;还是已经步入职场的小伙伴&#xff0c;都会遇到要对一些文档进行编辑处理&#xff0c;例如有时需要将word、excel、ppt等格式的文档与pdf文件进行相互转换&#xff0c;有时又需要对pdf文件进行编辑文档增加页眉页脚、拆分合并、加密解密等操…

基于Python+Echarts+Pandas 搭建一套图书分析大屏展示系统(附源码)

今天给大家分享的是基于 Flask、Echarts、Pandas 等实现的图书分析大屏展示系统。 项目亮点 采用 pandas、numpy 进行数据分析 基于 snownlp、jieba 进行情感分析 后端接口选用 RESTful 风格&#xff0c;构建 Swagger 文档 基于 Flask、Echarts 构建 Web 服务&#xff0c;采…

2022年债券估值工具和方法

第一章 债券估值原理概述 债券估值是决定债券公平价格[1]的过程。债券公平价格是债券的预期现金流经过合适的折现率折现以后的现值&#xff0c;其原理是未来现金流流出折现到今日与今日现金流流出相等。因此&#xff0c;债券的估值模型可以表示为&#xff1a; 资料来源&#x…

新冠阳性的第四篇博客,SpringBoot 任务(异步、定时、邮件)

新冠阳性的第四篇博客&#xff0c;SpringBoot 任务&#xff08;异步、定时、邮件&#xff09;1.异步任务2.邮件任务3.定时任务1.异步任务 异步处理还是非常常用的&#xff0c;比如我们在网站上发送邮件&#xff0c;后台会去发送邮件&#xff0c;此时前台会造成响应不动&#x…

Python多元线性回归、机器学习、深度学习在近红外光谱分析中的应用

导师&#xff1a;郁磊副教授&#xff0c;主要从事MATLAB 编程、机器学习与数据挖掘、数据可视化和软件开发、人工智能近红外光谱分析、生物医学系统建模与仿真&#xff0c;具有丰富的实战应用经验&#xff0c;主编《MATLAB智能算法30个案例分析》、《MATLAB神经网络43个案例分析…

【Vue】二、 认识Vue.js的各种指令

后端程序员的vue学习之路1、创建第一个vue对象2、vue构造器3、Vue.js模板语法v-text至v-for练习v-on指令练习v-bind指令练习v-model指定练习v-pre指令v-slot指令v-cloak指令v-once指令1、创建第一个vue对象 引入了vue.js后&#xff0c;在页面就可以创建一个Vue对象&#xff0c…

JS圣诞树

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。&#x1f34e;个人主页&#xff1a;Java Fans的博客&#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。&#x1f49e;当前专栏&#xff1a;前端案例分享…

this指向问题,apply,call,bind用法及区别

1.谁调用我&#xff0c;我就指向谁。 在页面上直接打印一个consle.log&#xff08;this&#xff09;,这个this会指向window对象。如果写一个函数&#xff1a;打印this,该this会指向window。因为这个函数是挂载在这个window对象上的。对象obj的this指向的是对象&#xff0c;因为…