hibernate多对多关系表的搭建和‘增删改查’

news2025/2/26 21:54:43

hibernate框架——数据库的多对多关系!

众所周知,数据库有三种数据模型,一对一,一对多,多对多,在前面的文章中主要介绍了一对一和一对多的表关系搭建和使用sql语句进行增删改查。

使用hibernate框架主要分为三步:

  1. 创建类

    • 类中需要包含表中需要的所有属性
  2. 创建映射文件

    • 映射文件需要包含刚刚创建的类的属性
  3. 添加配置文件

    • 将映射文件加入cfg.xml文件中

    创建多对多表关系

在这里演示的是hibernate建立数据库关系中的多对多关系,首先创建两个类,相信大家都玩过游戏,没有玩过也不要紧,不会妨碍我们去理解。这里我选择的是玩家和英雄,一个玩家可以拥有多个英雄,一个英雄也可以被多个玩家拥有。

//两个类的属性
//角色类
public class Role {
    private int rid;//英雄id
    private String name;//英雄姓名
    private String description;//描述信息
    Set<Player> players = new HashSet<>();//英雄所属角色
}
//玩家类
public class Player {
    private int pid;//玩家id
    private String name;//玩家姓名
    private String gender;//玩家性别
    Set<Role> roles = new HashSet<>();//玩家可拥有英雄
}
//这里只有属性,读者需要自行添加set和get方法

如果读者添加了其他属性,那么需要在映射文件中添加相对的属性,添加两个类映射文件,注意这里是以xml结尾的文件。

<!--这里是玩家的相关映射文件-->
<hibernate-mapping>
    <!--找到类所在之处,然后设置表名 tb_playe-->
    <class name="com.hbnu.pojo.Player" table="tb_player">
        <id name="pid"><!--设置主键-->
            <generator class="native"></generator>
        </id>
		<!--设置其他属性-->
        <property name="name"/>
        <property name="gander"/>
        <!-- table属性值表示第三张表的名称,这里使用了联级更新,更新了一张表,另外一张表也会更新-->
        <set name="roles" table="tb_pr" cascade="save-update ">
        <!--  pid表示在第三张表的外键名称-->
            <key column="pid"></key>
            <!--多对多
             class:表示多对多当前配置文件所属类的另外一方的全路径名称
             column:表示多对多当前配置文件所对应的另外一方表在第三张中间表中的名称-->
            <many-to-many class="com.hbnu.pojo.Role" column="rid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
<!--这里是角色的相关映射文件,因为这里和玩家的内容如出一格,这里便不再赘述-->
<hibernate-mapping>
    <class name="com.hbnu.pojo.Role" table="tb_role">
        <id name="rid">
            <generator class="native"></generator>
        </id>
        <!-- 不能使用关键字进行建表 -->
        <property name="name"/>
        <property name="description" />
        <set name="players" table="tb_pr">
            <key column="rid"></key>
            <many-to-many class="com.hbnu.pojo.Player" column="pid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

编写完映射类,不能忘记在核心配置文件中加入映射文件:

<mapping resource="com/hbnu/config/Player.xml"/>
<mapping resource="com/hbnu/config/Role.xml"/>

既然已经将表创建好,只需要在表中添加数据即可,可以编写代码也可以在数据库中操作。

在这里插入图片描述

添加的数据:

在这里插入图片描述

可以来测试一下表的增删改查

删除操作:

//多对多不要使用级联删除
    @Test
    public void testManyToManyDelete(){
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();//封装了静态数据库连接,直接调用即可
        Session session = sessionFactory.openSession();//设置session工厂
		//因为修改了表中数据,注意要使用事务处理
        Transaction transaction = session.beginTransaction();
        //获取id为2的玩家信息,将其删除
        Player player = session.get(Player.class, 2);
        session.delete(player);
        transaction.commit();
        //释放资源
        HibernateUtil.close(session,sessionFactory);
    }

在这里插入图片描述

可以看见表被创建,我们在三个表中添加数据,可以开始接下来的测试阶段。测试增删改查在多对多关系中是如何编写的,首先测试删除,这里要注意多对多不要使用级联删除,在一对多中可以使用,但是在这里会出现误删的情况。所以在关系映射表中的cascade="save-update, delete"将delete删除

接下来测试修改表

//修改多对多表数据
@Test
public void testManyToManyUpdate(){
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    //移除id为1玩家的id为2的角色
    Player player = session.get(Player.class, 1);
    Role role = session.get(Role.class, 2);
    //对一个玩家添加某个角色
    //player.getRoles().add(role);
    //该行可以省略,因为表中是直连状态,表中数据会自己更新
    //session.update(player);
    //对一个玩家去除某个角色
    player.getRoles().remove(role);
    transaction.commit();
    HibernateUtil.close(session,sessionFactory);
}

在这里插入图片描述

增加表中数据

public void testManyToManyInsert(){
    //添加一个玩家,将id为2的角色进行分配
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    Player player = new Player();//添加玩家
    player.setPid(3);
    player.setName("韩跳跳");
    player.setGander("男");
    Role role = session.get(Role.class,2);
    player.getRoles().add(role);//添加类
    session.save(player);//保存数据
    transaction.commit();
    HibernateUtil.close(session,sessionFactory);
}

在这里插入图片描述

查数据

//查询id为1的玩家拥有的英雄信息
@Test
public void testManyToManySelect(){
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
	//sql语句
    String sql = " select * from tb_player p,tb_role r,tb_pr pr where p.pid = pr.pid and r.rid = pr.rid and p.pid=:id";
    //预编译处理
    NativeQuery<Player> sqlQuery = session.createSQLQuery(sql);
    sqlQuery.addEntity(Player.class);
    sqlQuery.setParameter("id","1");
    //输出结果集
    List<Player> players = sqlQuery.list();
    //打印结果
    for (Player player : players) {
        System.out.println(player+"-->"+player.getRoles());
    }
}

在这里插入图片描述
今天的分享就到这里,学会hibnater框架对数据库的学习和利用框架搭建需要的表格就会变得超级便捷,当然,其实这种框架有很多,比如mybatis

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

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

相关文章

web集群第二次作业

文章目录 1. 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式&#xff0c;比较其各自的优势 。2. 基于 CentOS 7 构建 LVS-DR 群集。1、环境准备2、安装httpd准备两个web页面3、配置LVS负载均衡服务4、手工在RS端绑定VIP&#xff0c;添加本机访问VIP的路由信息5、手工在RS端抑制AR…

Turtle海龟画图

介绍 简单的一个窗口绘图工具。 提供一个小海龟&#xff0c;可以看做一个机器人&#xff0c;能够听得懂有限的命令。 三种命令 运动命令 forward(d) 向前移动D长度 backward(d) 向后移动D长度 right(d) 向右转动多少度 left(d) 向左转动多少度 goto(x,y) …

我让AI帮忙生成算法,Auto-GPT对比ChatGPT、文心一言,结果出人意料...

&#x1f34f;&#x1f350;&#x1f34a;&#x1f351;&#x1f352;&#x1f353;&#x1fad0;&#x1f951;&#x1f34b;&#x1f349;&#x1f95d; 我让AI帮忙生成算法&#xff0c;Auto-GPT对比ChatGPT、文心一言&#xff0c;结果出人意料… 文章目录 &#x…

如何在 Python 中获取字典交集

本文将讨论在 Python 中对两个或多个字典执行交集的不同方法。 文章目录 Python字典在 Python 中使用字典推导来交叉两个字典使用按位 & 运算符在 Python 中对两个字典进行交集使用 Set intersection() 方法在 Python 中将两个字典相交在 Python 中用于交叉多个字典的方法总…

C-预处理

文章目录 预处理宏定义数值宏常量字符串宏常量使用宏充当注释去注释和宏替换谁先进行 用define宏定义表达式在if判断语句之后多条语句没有{}导致出错 定义不能带空格 #undef 条件编译#ifdef ifndef:判定的是宏是否被定义#if-#endif:宏定义是否为真宏定义进行多条件筛选#ifdef &…

听好程序员一句劝!零基础这样学Java才是正确的方式!

有一说一&#xff0c;Java还是现在很多新手入门学习的首选之一&#xff0c;新手学Java入门从哪里开始学&#xff1f;很多入门的小伙伴都会疑惑&#xff0c;今天好程序员给大家分享一下&#xff0c;超适合菜鸟入门的 Java学习路线 第一步&#xff0c;JavaSE&#xff0c;这是Java…

工具类——Java导出EXCEL2(设置样式、加载并填充图片、加载指定模板、大数据量设置窗口大小与刷新频率)

文章目录 一、POI设置样式二、POI导出图片1.解释XSSFClientAnchor 三、加载指定模板导出四、&#x1f449;Workbook、XSSFWorkbook与SXSSFWorkbook1.大数据量导出1&#xff09;根据数据量选择XSSFWorkbook&#xff0c;还是SXSSFWorkbook 书接上篇&#xff1a;工具类——Java 浏…

机器学习笔记之密度聚类——DBSCAN方法(Python代码实现)

机器学习笔记之密度聚类——DBSCAN方法[Python代码实现] 引言基本思想概念介绍算法过程完整算法描述 DBSCAN \text{DBSCAN} DBSCAN的优点和缺陷 2023/4/25 \text{2023/4/25} 2023/4/25补充&#xff1a;基于 Python \text{Python} Python的代码实现 引言 本节将介绍密度聚类——…

【MySQL】索引与事务

索引&#xff1a; 什么是索引&#xff1f;为什么要⽤索引 为了提高查询效率而使用的一种数据结构把数据组织起来&#xff1b; 例如生活中的字典&#xff1a;声母&#xff0c;韵母&#xff0c;声调。 创建索引&#xff1a;自动创建的主键约束&#xff0c;唯一约束&#xf…

qiankun-微前端

项目结构 主应用&#xff1a; vue3 vite 子应用1&#xff1a;vue3 vite 背景介绍 项目采用了vue3vite构建的&#xff0c;又因为qiankun不支持vite&#xff0c;所以需要引用 vite-plugin-qiankun 插件来解决 主应用–改造 安装 qiankun npm install qiankun重新定义一个…

浅浅入门SpringBoot之Thymeleaf模板

Thymeleaf是一个流行的模板引擎,该模板引擎采用Java语言开发模板引擎是一个技术名词,是跨领域跨平台的概念,在Java语言体系下有模板引擎,在C#、PHP语言体系下也有模板引擎,甚至在 Javascript中也会用到模板引擎技术,Java生态下的模板引擎有 Thymeleaf、 Freemaker、Ⅴ elocity、…

【EMQX】EMQX管理控制台即EMQX Dashboard简介

EMQX管理控制台 一、EMQX Dashboard简介二、主要功能2.1 监控和管理 EMQX 集群中的相关信息与数据2.2 访问控制&#xff08;认证与授权&#xff09;管理2.3 数据集成2.4 在线配置热更新2.5 管理系统扩展能力2.6 全面的诊断工具 三、启动3.1 首次登录3.2 忘记密码 四、配置 Dash…

我老板:你根本不懂 React!

前言 我已经使用 React 多年&#xff0c;我确信我非常了解它&#xff0c;但最近我的老板对我说&#xff0c;“你根本不知道 React&#xff0c;你对它一无所知。” 我很生他的气&#xff0c;但他指出了我程序中的三个漏洞。我现在把它记录下来&#xff0c;也分享给还不知道的小…

用好ChatGPT,毕业直接走上人生巅峰

毕业论文交上去了&#xff0c;学分也攒齐了。考研没上岸的准毕业生们接下来要面对的不是惨烈的秋招&#xff0c;就是蹲家准备二战。生活终于要对各位小可爱们动手啦&#xff01; 不想默默承受社会的毒打&#xff1f; 不愿在屡战屡败屡败屡战的压力下秃头&#xff1f; 想必各位…

API 都有这些功能,你真的都知道么?

API&#xff08;应用程序编程接口&#xff09;可以提供以下功能&#xff1a; 数据传输&#xff1a;API可以在应用程序之间传输数据&#xff0c;包括发送和获取数据、更新数据等。 访问功能: API 可以调用另一个系统或应用程序的某些功能&#xff0c;例如获取天气&#xff0c;查…

基于无线传感器网络(WSN) 查找两个节点之间的最短路径并发送数据(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 本代码基于无线传感器网络&#xff0c;在两个节点&#xff08;源节点和目标节点&#xff09;之间找到最短路径&#xff0c;并开…

Java学习过程(韩顺平661-665)

网络通信是指在计算机网络中&#xff0c;通过网络连接的设备之间进行数据交换的过程。网络通信可以分为两种类型&#xff1a;有线网络通信和无线网络通信。 有线网络通信主要通过物理介质&#xff08;如光纤、双绞线等&#xff09;来传输数据&#xff0c;其中最常用的协议是以…

数字孪生新能源智慧充电桩Web3D可视化运维系统

放眼全球&#xff0c;近十年来&#xff0c;新能源汽车赛道堪称“热得发烫”。伴随着进入成年期的新能源汽车行业对相关配套设备支撑水平的提升&#xff0c;作为其“新基建”的充电桩领域表现更为突出的价值势能。过去&#xff0c;在一系列补贴政策和资本刺激下&#xff0c;充电…

七种MOS管栅极驱动电路

01 直接驱动 首先说一下电源IC直接驱动&#xff0c;下图是我们最常用的直接驱动方式&#xff0c;在这类方式中&#xff0c;我们由于驱动电路未做过多处理&#xff0c;因此我们进行PCB LAYOUT时要尽量进行优化。如缩短IC至MOSFET的栅极走线长度&#xff0c;增加走线宽度&#x…