Hibernate框架【五】——基本映射——多对多映射

系列文章目录

Hibernate框架【三】——基本映射——一对一映射
Hibernate框架【四】——基本映射——多对一和一对多映射


基本映射——多对多映射

  • 系列文章目录
  • 前言
  • 一、多对多映射是什么?
  • 二、hibernate多对多关联映射(单向)
    • 1.实体结构
    • 2.示意图
    • 3.对应的实体xml配置文件
    • 4.生成的表结构
    • 5.核心代码
      • 1.插入数据
      • 2.查询数据
  • 三、hibernate多对多关联映射(双向)
    • 1.实体结构
    • 2.对应实体的xml配置文件
    • 3.生成的表结构
    • 4.核心代码
      • 1.插入数据
      • 2.查询数据(先查User)
      • 3.查询数据(先查Role)
  • 四、总结


前言

由于公司项目上进行面向对象的架构设计对于ORM部分使用的是Spring Data JPA框架。将ORM完全交给Spring Data JPA框架,而Hibernate是Spring Data JPA的实现方式之一,通过对HIbernate框架的学习能够更好的理解ORM框架,以及Spring Data JPA框架。
下面的博客是对于Hibernate框架中的基本映射中的一对一映射进行的实践,总结的并不全面,旨在对于一对一映射关系有一个宏观了解并能够进行基本运用。


一、多对多映射是什么?

在Hibernate中,多对多映射表示多个实体之间的多对多关系,其中一个实体可以与多个另一实体相关联,并且每个另一实体也可以与多个该实体相关联。
在多对多映射中,需要创建一个中间表(关联表)来存储实体之间的关联关系。该中间表通常包含两个外键列,分别指向参与关联的两个实体的主键。
当然多对多映射关系,也分为单向关联和双向关联。

二、hibernate多对多关联映射(单向)

案例:现在有两个实体User实体和Role,分别表现出多对多的关系,一个用户可以有多个角色,一个角色可以包含多个用户。

1.实体结构

package com.wangwei.hibernate;

import java.util.Set;

public class User {
    
    private int id;
    
    private String name;

    private Set roles;
    
    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 Set getRoles() {
        return roles;
    }

    public void setRoles(Set roles) {
        this.roles = roles;
    }
}

package com.wangwei.hibernate;

public class Role {

    private int id;
    
    private String name;
    
    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;
    }
}

2.示意图

在这里插入图片描述

3.对应的实体xml配置文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.wangwei.hibernate.Role" table="t_role">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.wangwei.hibernate.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="roles" table="t_user_role">
            <key column="user_id"/>
            <many-to-many class="com.wangwei.hibernate.Role" column="role_id" />    
        </set>
    </class>
</hibernate-mapping>

4.生成的表结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.核心代码

1.插入数据

public class Many2ManyTest extends TestCase {

    public void testSave1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Role r1 = new Role();
            r1.setName("数据录入人员");
            session.save(r1);
            
            Role r2 = new Role();
            r2.setName("商务主管");
            session.save(r2);
            
            Role r3 = new Role();
            r3.setName("商务经理");
            session.save(r3);
            
            Role r4 = new Role();
            r4.setName("项目会计");
            session.save(r4);
            
            User u1 = new User();
            u1.setName("张三");
            Set u1Roles = new HashSet();
            u1Roles.add(r1);
            u1Roles.add(r2);
            u1.setRoles(u1Roles);
            session.save(u1);
            
            User u2 = new User();
            u2.setName("李四");
            Set u2Roles = new HashSet();
            u2Roles.add(r1);
            u2Roles.add(r2);
            u2Roles.add(r3);
            u2.setRoles(u2Roles);
            session.save(u2);
            
            User u3 = new User();
            u3.setName("王五");
            Set u3Roles = new HashSet();
            u3Roles.add(r3);
            u3Roles.add(r4);
            u3.setRoles(u3Roles);
            session.save(u3);
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }    

发出的SQL语句
在这里插入图片描述
数据库中的数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.查询数据

public void testLoad1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            User user = (User)session.load(User.class, 2);
            System.out.println(user.getName());
            for (Iterator iter=user.getRoles().iterator(); iter.hasNext();) {
                Role role = (Role)iter.next();
                System.out.println(role.getName());
            }
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }        

发出的sql语句和打印的结果
在这里插入图片描述

三、hibernate多对多关联映射(双向)

1.实体结构

package com.wangwei.hibernate;

import java.util.Set;

public class Role {

    private int id;
    
    private String name;
    
    private Set User;
    
    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 Set getUser() {
        return User;
    }

    public void setUser(Set user) {
        User = user;
    }
    
}

package com.wangwei.hibernate;

import java.util.Set;

public class User {
    
    private int id;
    
    private String name;

    private Set roles;
    
    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 Set getRoles() {
        return roles;
    }

    public void setRoles(Set roles) {
        this.roles = roles;
    }
}

2.对应实体的xml配置文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.wangwei.hibernate.Role" table="t_role">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="user" table="t_user_role">
            <key column="role_id" not-null="true"/>
            <many-to-many class="com.wangwei.hibernate.User" column="user_id"/>
        </set>
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.wangwei.hibernate.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="roles" table="t_user_role">
            <key column="user_id"/>
            <many-to-many class="com.wangwei.hibernate.Role" column="role_id" />    
        </set>
    </class>
</hibernate-mapping>

注意事项:

  • 生成的中间表名称必须一样
  • 生成的中间表中的字段必须一样

3.生成的表结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.核心代码

1.插入数据

public void testSave1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Role r1 = new Role();
            r1.setName("数据录入人员");
            session.save(r1);
            
            Role r2 = new Role();
            r2.setName("商务主管");
            session.save(r2);
            
            Role r3 = new Role();
            r3.setName("商务经理");
            session.save(r3);
            
            Role r4 = new Role();
            r4.setName("项目会计");
            session.save(r4);
            
            User u1 = new User();
            u1.setName("张三");
            Set u1Roles = new HashSet();
            u1Roles.add(r1);
            u1Roles.add(r2);
            u1.setRoles(u1Roles);
            session.save(u1);
            
            User u2 = new User();
            u2.setName("李四");
            Set u2Roles = new HashSet();
            u2Roles.add(r1);
            u2Roles.add(r2);
            u2Roles.add(r3);
            u2.setRoles(u2Roles);
            session.save(u2);
            
            User u3 = new User();
            u3.setName("王五");
            Set u3Roles = new HashSet();
            u3Roles.add(r3);
            u3Roles.add(r4);
            u3.setRoles(u3Roles);
            session.save(u3);
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }    

生成的sql语句
在这里插入图片描述
表中的数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.查询数据(先查User)

public void testLoad1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            User user = (User)session.load(User.class, 2);
            System.out.println(user.getName());
            for (Iterator iter=user.getRoles().iterator(); iter.hasNext();) {
                Role role = (Role)iter.next();
                System.out.println(role.getName());
            }
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }        

发出的sql语句和打印的结果

在这里插入图片描述

3.查询数据(先查Role)

public void testLoad2() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            Role role = (Role)session.load(Role.class, 1);
            System.out.println(role.getName());
            for (Iterator iter=role.getUser().iterator(); iter.hasNext();) {
                User user = (User)iter.next();
                System.out.println(user.getName());
            }
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }        

发出的sql语句和结果
在这里插入图片描述

四、总结

如何选择多对多的单向关联还是多项关联。主要取决于实际的业务需要。
1.如果只需要从一个实体导航到另一个实体,而无需反向导航,那么使用单向关联更为合适。
2.如果不需要再两个实体上进行关系的维护,添加、删除、更新等,那么单向关联更合适。
3.维护上:单向关联不会引入额外的的关系

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大麦一键生成订单截图 大麦生成购票链接

一键生成订单截图&#xff0c;生成购票链接 已对接支付 下载程序&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

【并发篇】04-05 线程池核心参数代码演示

B站 黑马程序员 java八股的视频笔记 自留备忘 如有错误请多多指教。 &#xff08;一&#xff09;理论知识 这道题其实就是在问java中线程池的实现类ThreadPoolExecutor&#xff0c;这个类参数最多的构造方法有7个参数。 线程池本质上就是管理一组线程&#xff0c;用来执行提交…

2023最新最全面Java复习路线(含P5-P8),已收录 GitHub

小编整理出一篇 Java 进阶架构师之路的核心知识&#xff0c;同时也是面试时面试官必问的知识点&#xff0c;篇章也是包括了很多知识点&#xff0c;其中包括了有基础知识、Java 集合、JVM、多线程并发、spring 原理、微服务、Netty 与 RPC 、Kafka、日记、设计模式、Java 算法、…

音视频技术开发周刊 | 297

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 Geenee AR为品牌商和零售商提供虚拟试穿应用 这意味着Geenee AR的虚拟试穿解决方案能够与品牌商现有的销售渠道无缝集成。 谁说苹果掉队了&#xff1f;WWDC上只字未提AI&a…

九种分布式ID解决方案

背景 在复杂的分布式系统中&#xff0c;往往需要对大量的数据进行唯一标识&#xff0c;比如在对一个订单表进行了分库分表操作&#xff0c;这时候数据库的自增ID显然不能作为某个订单的唯一标识。除此之外还有其他分布式场景对分布式ID的一些要求&#xff1a; 趋势递增&#…

java SSM 宿舍管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 宿舍管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/…

JVM零基础到高级实战之内存区域分布与概述

JVM零基础到高级实战之内存区域分布与概述 JVM零基础到高级实战之内存区域分布与概述 文章目录 JVM零基础到高级实战之内存区域分布与概述前言Java语言为甚么优势巨大&#xff1f;总结 前言 JVM零基础到高级实战之内存区域分布与概述 Java语言为甚么优势巨大&#xff1f; 一处…

强大的工具:APISpace IP归属地查询API

引言 IP地址在互联网世界中扮演着重要的角色&#xff0c;对于许多应用程序和服务来说&#xff0c;了解IP地址的归属地信息可以提供有价值的洞察和功能。 在本文中&#xff0c;我们将介绍一种名为IP归属地-IPv4区县级 API 的强大工具&#xff0c;它提供了查询 IP 地址归属地信…

网内计算:可编程数据平面和技术特定应用综述

网内计算&#xff1a;可编程数据平面和技术特定应用综述 摘要——与云计算相比&#xff0c;边缘计算提供了更靠近终端设备的处理&#xff0c;降低了用户体验的延迟。最新的In-Network Computing范例采用可编程网络元素在数据达到边缘或云服务器之前计算&#xff0c;促进了常见…

《百年孤独》15句经典语录

句句都是人生真相&#xff0c;说透了所有人的孤独。 1、生命中曾经有过的所有灿烂&#xff0c;原来终究&#xff0c;都需要用寂寞来偿还。 2、过去都是假的&#xff0c;回忆是一条没有尽头的路。 这句话是最受读者欢迎的一句话&#xff0c;回忆就是一条没有尽头的路&#xf…

【嵌入式环境下linux内核及驱动学习笔记-(16)linux总线、设备、驱动模型之input框架】

目录 1、Linux内核输入子系统概念导入1.1 输入设备工作机制1.2 运行框架1.3 分层思想 2、驱动开发步骤2.1 在init()或probe()函数中2.2 在exit&#xff08;&#xff09;或remove&#xff08;&#xff09;函数中&#xff1a;2.3 上报事件2.4 input驱动要素导图2.5 input驱动的总…

LVS负载均衡群集部署——DR直接路由模式

这里写目录标题 一 、 LVS-DR 工作原理二、数据包流向分析三、LVS-DR 模式的特点四、ARP问题4.1 问题一&#xff1a;IP地址冲突4.2 问题二&#xff1a;第二次再有访问请求 五、部署LVS-DR集群5.1 配置Tomcat 多实例服务器5.2 配置web节点服务器配置web1节点服务器配置Nginx七层…

Flutter进阶篇-布局(Layout)原理

1、约束、尺寸、位置 overrideWidget build(BuildContext context) {return Scaffold(body: LayoutBuilder(builder: (context, constraints) {print("body约束:" constraints.toString());return Container(color: Colors.black,width: 300,height: 300,child: L…

MATLAB | 绘图复刻(九) | 泰勒图及组合泰勒图

有粉丝问我这个图咋画&#xff1a; 我一看&#xff0c;这不就泰勒图嘛&#xff0c;就fileexchange上搜了一下泰勒图绘制代码&#xff0c;但是有的代码比较新的版本运行要改很多地方&#xff0c;有的代码需要包含一些压缩包没并没有的别人写的函数&#xff0c;于是我干脆自己写了…

【MySQL 数据库】11、学习 MySQL 中的【锁】

目录 一、锁的概述与分类二、全局锁&#xff08;全库数据备份&#xff09;三、表级锁(1) 表锁(2) 元数据锁&#xff08;Meta Data Lock&#xff09;(3) 意向锁 四、行级锁(1) 行锁(2) 间隙锁&临键锁 一、锁的概述与分类 锁是计算机协调多个进程或线程并发访问某一资源的机…

国产Gauss 分布式数据库概述

一、前言 GaussDB 是华为2023年6月7日发布新一代分布式数据库&#xff0c;采用share-nothing架构&#xff0c;数据自动分片&#xff0c;通过GTM-Lite技术实现事务强一致&#xff0c;无中心节点性能瓶颈&#xff0c;是华为基于openGauss自主创新研发的一款分布式关系型数据库&am…

STM32CubeMX | 44 - 使用GPIO点亮单总线RGBLED

一、单总线RGBLED 1. 硬件连接 在DragonFly上有四个全彩灯相连: 其中RGB_LED连接到STM32的PB9引脚。 2. 单总线通信协议 单总线通信协议中,表示bit0和bit1的码型如下: 时序值如下: 驱动一个单总线RGBLED只需要传输24bit颜色数据即可(MSB,高位优先),格式如下(注意…

C++设计模式 - 创建型模式之工厂模式

文章目录 C设计模式 - 创建型模式之工厂模式接口和针对接口编程 1. 简单工厂模式适用场合UML代码示例 2. 工厂方法模式适用场合UML代码示例 3. 抽象工厂模式适用场合UML代码示例 总结 C设计模式 - 创建型模式之工厂模式 工厂模式属于创建型模式&#xff0c;大致可以分为三类&a…

力扣 209. 长度最小的子数组

一、题目描述 给定一个含有 n 个正整数的数组和一个正整数 target。 找出该数组中满足其和大于等于 target 的长度最小的连续子数组&#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0。 示例 1&#xff1a; 输入&#xff1a;target 7, nums [2,3,1…

Uni-app学习从0到1开发一个app——(3)简单小工程内容介绍

文章目录 工程文件 看看一个标准的hello微信小程序工程文件的组成和作用。 工程文件 可以参考官方教程&#xff1a;传送门 之前的文章有详细的开发环境介绍&#xff0c;传送门Uni-app学习从0到1开发一个app——(2)windowns环境搭配&#xff0c;这里我们先建一个简单的示例微信…