Hibernate多表的关联关系、懒加载

news2025/1/11 11:11:09

一、一对多关系:插入:

“一”的一方为主表,“多”的一方为副表,主表关联副表,应该在主表中加入副表对象作为属性。
根据顾客ID插入顾客信息 (一) ,同时将顾客名下所有订单插入 (多)

实现思路:
在这里插入图片描述

  • 数据库关系:
    在这里插入图片描述
  • 创建顾客实体类,存储顾客信息:
    注意我们在顾客类中用List集合封装了顾客名下的订单信息。
package org.example.Entity;

import java.util.List;
public class CustomerEntity {
    private int id;
    private String name;
    private Integer age;
    //在顾客表中加入订单集合
    private List<OrdersEntity> orders;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public List<OrdersEntity> getOrders() {
        return orders;
    }

    public void setOrders(List<OrdersEntity> orders) {
        this.orders = orders;
    }
}
  • 创建订单类,存储订单信息:
    订单类中应该有顾客类,用来指明该订单属于哪个顾客。
package org.example.Entity;

public class OrdersEntity {
    private int id;
    private String orderNumber;
    private Double orderPrice;
    //订单中有外键customer_id,所以需要添加顾客类
    private CustomerEntity customer;

    public int getId() {
        return id;
    }

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

    public String getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }

    public Double getOrderPrice() {
        return orderPrice;
    }

    public void setOrderPrice(Double orderPrice) {
        this.orderPrice = orderPrice;
    }

    public CustomerEntity getCustomer() {
        return customer;
    }

    public void setCustomer(CustomerEntity customer) {
        this.customer = customer;
    }
}
  • 创建顾客关系类的映射文件:
<?xml version='1.0' encoding='utf-8'?>
<!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="org.example.Entity.CustomerEntity" table="customer" schema="ssm">
        <!--主键-->
        <id name="id" column="id" type="java.lang.Integer"/>
        <!--非主键-->
        <property name="aid" column="aid" type="java.lang.Integer"/>
        <property name="cid" column="cid" type="java.lang.Integer"/>
        <!--配置集合属性orders 和表名orders-->
        <set name="orders" table="orders">
            <!--该属性对应的外键-->
            <key column="customer_id"/>
            <!--该外键所属的实体类-->
            <one-to-many class="org.example.Entity.OrdersEntity"/>
        </set>
    </class>
</hibernate-mapping>
  • 创建订单实体类的映射文件:
<?xml version='1.0' encoding='utf-8'?>
<!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="org.example.Entity.OrdersEntity" table="orders" schema="ssm">
        <!--主键,type接封装类,class接自定义类-->
        <id name="id" column="id" type="java.lang.Integer"/>
        <!--非主键-->
        <property name="orderNumber" column="orderNumber" type="java.lang.String"/>
        <property name="orderPrice" column="orderPrice" type="java.lang.Double"/>
        <!--外键,class是外键对应的实体类-->
        <many-to-one name="customer"  column="customer_id" class="org.example.Entity.CustomerEntity"/>

    </class>
</hibernate-mapping>
  • 测试类:
    注意要建立关联关系。
package org.example;

import org.example.Entity.CustomerEntity;
import org.example.Entity.OrdersEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class AppTest{
    @Test
    public void test(){
        //创建SessionFactory,从根路径下获取核心配置文件
        SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
        //创建session
        Session session = factory.openSession();
        //创建事务
        Transaction transaction = session.beginTransaction();
        //创建顾客类对象并给相应属性赋值
        CustomerEntity customer = new CustomerEntity();
        customer.setId(4);
        customer.setName("44");
        customer.setAge(18);
        //创建订单类对象并给相应属性赋值
        OrdersEntity order = new OrdersEntity();
        order.setId(4);
        order.setOrderNumber("4");
        order.setOrderPrice(4.0);
        //建立关联关系,若不建立关联关系order表的数据为空
        order.setCustomer(customer);
        //保存,所有对象都要保存
        session.save(customer);
        session.save(order);
        //提交事务
        transaction.commit();
        //关闭SessionFactory
        factory.close();
    }
}
  • 运行结果:
    在这里插入图片描述

二、多对多关系:插入:

多对多关系通过一个中间表来维护。

实现思路:
在这里插入图片描述

  • 数据库关系:
    在这里插入图片描述
  • 创建Accounts实体类:
package org.example.Entity;

import java.util.Set;

public class AccountsEntity {
    private int aid;
    private String aname;
    private Set<CoursesEntity> courses;

    public int getAid() {
        return aid;
    }

    public void setAid(int aid) {
        this.aid = aid;
    }

    public String getAname() {
        return aname;
    }

    public void setAname(String aname) {
        this.aname = aname;
    }

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

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

  • 创建Courses实体类:
package org.example.Entity;

import java.util.Set;

public class CoursesEntity {
    private int cid;
    private String cname;
    private Set<AccountsEntity> accounts;

    public int getCid() {
        return cid;
    }

    public void setCid(int cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

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

    public void setAccounts(Set<AccountsEntity> accounts) {
        this.accounts = accounts;
    }
}
  • 创建中间表实体类:
package org.example.Entity;

public class AccountCourseEntity {
    private int id;
    private Integer aid;
    private Integer cid;

    public int getId() {
        return id;
    }

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

    public Integer getAid() {
        return aid;
    }

    public void setAid(Integer aid) {
        this.aid = aid;
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }
}
  • 创建Accounts实体类映射文件:
<?xml version='1.0' encoding='utf-8'?>
<!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="org.example.Entity.AccountsEntity" table="accounts" schema="ssm">
        <id name="aid" column="aid" type="java.lang.Integer"/>
        <property name="aname" column="aname" type="java.lang.String"/>
        <set name="courses" table="account_course">
            <key column="aid"/>
            <!--column 属性与中间表的外键字段名对应,这里配的是CoursesEntity在中间表中对应的外键-->
            <many-to-many class="org.example.Entity.CoursesEntity" column="cid"/>
        </set>
    </class>
</hibernate-mapping>
  • 创建Courses实体类映射文件:
<?xml version='1.0' encoding='utf-8'?>
<!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="org.example.Entity.CoursesEntity" table="courses" schema="ssm">
        <id name="cid" column="cid" type="java.lang.Integer"/>
        <property name="cname" column="cname" type="java.lang.String"/>
        <set name="accounts" table="account_course">
            <key column="cid"/>
            <!--column 属性与中间表的外键字段名对应,这里配的是AccountsEntity在中间表中对应的外键-->
            <many-to-many class="org.example.Entity.AccountsEntity" column="aid"/>
        </set>
    </class>
</hibernate-mapping>
  • 创建中间表实体类映射文件:
<?xml version='1.0' encoding='utf-8'?>
<!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="org.example.Entity.AccountCourseEntity" table="account_course" schema="ssm">
        <id name="id" column="id" type="java.lang.Integer"/>
        <property name="aid" column="aid" type="java.lang.Integer"/>
        <property name="cid" column="cid" type="java.lang.Integer"/>
    </class>
</hibernate-mapping>
  • 测试类:
package org.example;

import org.example.Entity.AccountsEntity;
import org.example.Entity.CoursesEntity;
import org.example.Entity.CustomerEntity;
import org.example.Entity.OrdersEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import java.util.HashSet;
import java.util.Set;

public class AppTest{

    @Test
    public void test2(){
        //创建SessionFactory,从根路径下获取核心配置文件
        SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
        //创建session
        Session session = factory.openSession();
        //创建事务
        Transaction transaction = session.beginTransaction();
        //创建Courses类对象并给相应属性赋值
        CoursesEntity course = new CoursesEntity();
        course.setCname("JAVA");
        //创建Accounts类对象并给相应属性赋值
        AccountsEntity account = new AccountsEntity();
        account.setAname("张三");
        //建立关联关系
        Set<CoursesEntity> courses = new HashSet<>();
        courses.add(course);
        account.setCourses(courses);
        //保存,所有对象都要保存
        session.save(course);
        session.save(account);
        //提交事务
        transaction.commit();
        //关闭SessionFactory
        factory.close();
    }
}
  • 运行结果:
    在这里插入图片描述

三、一对多关系:查询+懒加载:

懒加载条件下查询顾客信息和订单信息。

什么是懒加载?点击查看

具体配置同(一)。
需要在customer类的映射文件中为order的set集合配置 lazy="true",设置order的懒加载,这样在查询customer信息时会根据需求判断是否查询order。
需要在order类的映射文件中为customer的many-to-one设置lazy=proxy",设置customer的懒加载,这样在查询order信息时会根据需求判断是否查询customer。

  • 测试类1:
@Test
public void test3(){
    //创建SessionFactory,从根路径下获取核心配置文件
    SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
    //创建session
    Session session = factory.openSession();
    //创建事务
    Transaction transaction = session.beginTransaction();
    //查询主键为4的顾客信息
    CustomerEntity customer = session.get(CustomerEntity.class,4);
    System.out.println(customer);
    //提交事务
    transaction.commit();
    //关闭SessionFactory
    factory.close();
}
  • 运行结果1:

因为会调用toString方法,toString会打印学生信息和订单信息,所以有两条SQL语句。
在这里插入图片描述
如果只打印customer.name(),则只会有第一条SQL,这就是懒加载。

  • 测试类2:
@Test
public void test4(){
    //创建SessionFactory,从根路径下获取核心配置文件
    SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
    //创建session
    Session session = factory.openSession();
    //创建事务
    Transaction transaction = session.beginTransaction();
    //查询主键为4的订单信息
    OrdersEntity orders = session.get(OrdersEntity.class,4);
    System.out.println(orders);
    //提交事务
    transaction.commit();
    //关闭SessionFactory
    factory.close();
}
  • 运行结果2:
    在这里插入图片描述
    如果只打印order.name(),则只会有第一条SQL,这就是懒加载。

四、多对多关系:查询+懒加载:

具体配置同(二)。
需要在account类的映射文件中为account_course的set集合配置 lazy="true",设置account_course的懒加载,这样在查询account信息时会根据需求判断是否查询course。
需要在course类的映射文件中为account_course的set集合设置lazy="true",设置account_course的懒加载,这样在查询course信息时会根据需求判断是否查询account。

  • 测试类1:
@Test
public void test5(){
    //创建SessionFactory,从根路径下获取核心配置文件
    SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
    //创建session
    Session session = factory.openSession();
    //创建事务
    Transaction transaction = session.beginTransaction();
    //查询主键为1的课程信息
    CoursesEntity course = session.get(CoursesEntity.class,1);
    System.out.println(course.toString());
    //提交事务
    transaction.commit();
    //关闭SessionFactory
    factory.close();
}
  • 测试结果1:
    在这里插入图片描述
  • 测试类2:
@Test
public void test5(){
    //创建SessionFactory,从根路径下获取核心配置文件
    SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
    //创建session
    Session session = factory.openSession();
    //创建事务
    Transaction transaction = session.beginTransaction();
    //查询主键为1的课程信息
    AccountsEntity account = session.get(AccountsEntity.class,1);
    System.out.println(account.toString());
    //提交事务
    transaction.commit();
    //关闭SessionFactory
    factory.close();
}
  • 测试结果2:
    在这里插入图片描述

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

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

相关文章

Python实现人脸识别检测,对主播进行颜值排行

前言 嗨嗨&#xff0c;我亲爱的家人们 今天来整点不一样的&#xff0c;嘿嘿 用Python简单实现对人脸识别的检测&#xff0c;对某平台主播照片进行评分排名 应该对女主播这个词不陌生吧&#xff0c;怎么说应该还是蛮多人看过一些女主播吧 我无聊的时候也会看看&#xff0c;…

2009年数学二真题复盘

选择题: 间断点的判断的前置芝士: 间断点的定义 设函数f(x)在点的去心领域内有定义,若f(x)满足以下条件之一: 在x=没有定义在x=有定义,但是不存在,或者存在,但是极限值不等于函数值。 类型定义 相关概念第一类间断点

CMS垃圾回收器

概述 CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上&#xff0c;这种垃圾回收器非常适合。在启动JVM参数加上-XX:UseConcMarkSweepGC&#xff0c;这个参数表示对于老年代的回收采用CMS。CMS采用的基础算…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.13 j2cache 相关配置

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.13 j2cache 相关配置5.13.1 j2cache 相关配置5.13…

直播绿幕抠图的例子(绿幕抠图直播实例参考)

阿酷TONY / 2022-11-21 / 长沙 什么是绿幕抠图&#xff1a; 设定绿幕或绿布&#xff0c;做直播软件抠图&#xff0c;这时绿幕绿布就可以被实时的抠掉&#xff0c;绿色就变成透明了&#xff0c;只剩下绿幕外的人物&#xff0c;此时添加上直播的背景画质&#xff0c;就实现了绿…

Git——Git常用命令

目录 常用命令概览 1. 设置用户签名 2. 初始化本地库 2.1 初始化本地库 2.2 查看文件 2.3 查看隐藏文件 2.4 进入到下一个目录 3. 查看本地库状态 4.添加暂存区 4.1 删除文件 5. 提交本地库 5.1 将暂存区的文件提交到本地库 6. 查看版本信息的命令 7.修改文件 8. 历史版本…

【Python入门指北】服务器信息清洗

服务器信息清洗 文章目录服务器信息清洗一、 subprocess 执行本机命令二、 获取服务器的硬件基础信息1. 基础信息2. 厂家和产品信息3. CPU 信息3.1 查看物理CPU型号3.2 查看物理CPU颗数3.3 查看每颗物理 CPU 的核心数4. 内存信息练习内存处理参考代码一、 subprocess 执行本机命…

智云通CRM:如何提前识别哪些客户爱说“不”?

有人说&#xff0c;做业务是最好的锻炼意志力方法&#xff0c;因为做业务的人经常会被客户拒绝甚至会扫地出门。被拒绝时&#xff0c;业务员一定要擦亮眼睛&#xff0c;善于察言观色&#xff0c;洞察客户的心理活动。透过观察了解客户为什么说“不”&#xff0c;客户拒绝情况有…

聚观早报 | 推特临时培训员工应对世界杯;世界杯足球内置传感器

今日要闻&#xff1a;推特临时培训员工应对世界杯;京东靠降本增效实现转亏为盈;世界杯足球内置传感器;艾格重返迪士尼CEO职位;特斯拉明年或开启收购计划 推特临时培训员工应对世界杯 据消息&#xff0c; 2022年世界杯拉开帷幕&#xff0c;推特的使用量即将激增&#xff0c;其维…

陆地卫星(Landsat)计划:50多年的星球档案

陆地卫星计划&#xff1a;陆地卫星1号至陆地卫星9号 1967年&#xff0c;NASA&#xff08;美国国家航空与航天局&#xff09; 提出了“地球资源技术卫星”计划&#xff0c;从此开始了在理论上对地球资源技术卫星系列的可行性研究&#xff0c;于是&#xff0c;陆地卫星 (Landsat…

汽车安全气囊设计?Abaqus/Part特殊建模方法-附案例step-by-step教学

作者 | 邓怡超 Abaqus/Part基于特征的建模功能可以说非常齐全&#xff0c;基本能够满足一般的分析要求&#xff0c;更复杂的模型则可以通过与专业三维建模软件之间的接口来导入&#xff0c;今天要说的是部件的另外一种建模方法。 有一种类型的分析&#xff0c;部件自身的初始…

坚持自学软件测试,半年的辛苦没有白费,不过才拿到10k的offer

找软件测试的工作只用了一周的时间&#xff0c;因为自己的年纪已经25岁&#xff0c;所以在简历上包装了两年的工作经验&#xff0c;但是我学的技术水平自认为还可以&#xff0c;因为我当时自学时用的教程比较有深度。 之所以要转行&#xff0c;我相信做机械工作的朋友都明白&a…

神经网络-前向传播Forward propagation

前向传播Forward propagation 前向传播算法就是&#xff1a; 将上一层的输出作为下一层的输入&#xff0c;并计算下一层的输出&#xff0c;一直到运算到输出层为止 在正式介绍前向传播前&#xff0c;先简单介绍计算图&#xff08;Computational Graph&#xff09;的概念。 yw…

LiDAR 完整指南介绍:激光探测和测距

什么是激光探测和测距 (LiDAR)&#xff1f; LiDAR 的全称是 Light Detection and Ranging (激光探测及测距)&#xff0c;LIDAR 是一种主动测量方式&#xff0c;主要由激光发射部分、接收部分组成、信号处理部分组成&#xff0c;从其名称可以发现 LIDAR 的两个主要基本功能是测…

关于我的家乡网页设计主题题材——梧州14页HTML+CSS网页

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

iOS关于列表布局的几种实现方式小结

式 &#xff0c;功能的要求是最多六行&#xff0c;动态展示。当时想到的方案是&#xff0c;抽象出一个cell,初始化六个标签&#xff0c;动态的控制显示和隐藏&#xff0c;这样功能上没有问题&#xff0c;就是代码有些冗余。请教了身边的美女同事&#xff0c;她那边的思路是用UI…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.17 发送多部件邮件

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.17 发送多部件邮件5.17.1 发送多部件邮件5.17.2 添…

Python脚本之并发执行加密方法【一】

本文为博主原创&#xff0c;未经授权&#xff0c;严禁转载及使用。 本文链接&#xff1a;https://blog.csdn.net/zyooooxie/article/details/125650427 之前写过一篇 JMeter性能测试之参数加密【一】&#xff0c;现在把后面的补上。实际第一篇就写完了 JMeter压测遇到加密接口…

Java Class11

Java Class11 集合 概念 集合是用于存储对象的工具类容器&#xff0c;实现了常用的数据结构&#xff0c;提供了一系列公开的方法用于删除、修改、查找和遍历数据&#xff0c;降低了日常开发成本。 三种集合 Set set集合中元素是无序、不可重复的 List list集合中元素是从前到…

公众号免费搜题功能搭建

公众号免费搜题功能搭建 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&#xf…