首页 > 其他分享 >Hibernate框架【五】——基本映射——多对多映射

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

时间:2023-06-18 10:38:42浏览次数:37  
标签:Hibernate 映射 框架 session Role User new public name


系列文章目录

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.示意图

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

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.生成的表结构

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


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


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

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语句

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


数据库中的数据

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


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


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

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框架【五】——基本映射——多对多映射_hibernate_09

三、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.生成的表结构

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


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


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

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语句

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


表中的数据

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


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


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

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语句和打印的结果

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

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语句和结果

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

四、总结

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


标签:Hibernate,映射,框架,session,Role,User,new,public,name
From: https://blog.51cto.com/u_15916106/6507332

相关文章

  • pytest + yaml 框架 -37.mark 标记对用例运行时长断言
    前言pytest执行用例的时候,我们希望对用例的运行时间断言,当用例执行时长大于预期标记此用例失败。@pytest.mark.runtime(1)运行时长单位是秒此插件已打包上传到pypihttps://pypi.org/project/pytest-runtime-yoyo/1.0.0/环境准备pipinstallpytest-yaml-yoyo此功能在v1.3.1版......
  • pytest + yaml 框架 -38.企业微信机器人通知
    前言v1.3.2版本支持企业微信机器人发送报告通知了。pipinstallpytest-yaml-yoyo获取企业微信机器人token企业机器人相关接口可以看官方文档https://developer.work.weixin.qq.com/document/path/91770创建群聊机器人获取到webhook访问地址https://qyapi.weixin.qq.com/cgi-bin/......
  • 【技术积累】Java中的集合框架【一】
    什么是Java集合框架?Java集合框架是Java编程语言中提供的一组接口、实现和算法,用于存储和操作数据集合。集合框架可以让程序员更加高效地组织和操作数据,而无需手动实现底层数据结构。Java集合框架的优点是:提供了丰富、灵活的数据结构和算法,让程序员可以更加高效地完成各种数据......
  • 人工智能、AI、深度学习框架
    深度学习的框架TensorFlowPytorchPaddlePaddle深度学习模型CNNLSTMAttention机制Seq2Seq损失函数优化方法特征表示 TRANSLATEwithxEnglishArabicHebrewPolishBulgarianHindiPortugueseCatalanHmongDawRomanianChineseSimplif......
  • 自动化测试的框架
    自动化测试框架是指为了支持自动化测试而开发的一套软件框架,它可以提供一些常用的测试功能,例如测试用例管理、结果统计、报告生成等。使用自动化测试框架可以大大提高测试的效率和准确性。以下是一些常见的自动化测试框架:RobotFramework:基于Python的自动化测试框架,通过关键字驱动......
  • 【框架源码】Spring源码解析之Bean创建源码流程
    问题:Spring中是如何初始化单例bean的?我们都知道Spring解析xml文件描述成BeanDefinition,解析BeanDefinition最后创建Bean将Bean放入单例池中,那么Spring在创建Bean的这个过程都做了什么。Spring核心方法refresh()中最最重要的一个方法finishBeanFactoryInitialization()方法,该方法......
  • Spring框架中的线程池
    Spring框架中的线程池使用Java的ExecutorService接口实现ExecutorService是Java提供的用于管理线程池的高级工具。下面是在Spring框架中使用线程池的一般步骤:导入所需的依赖首先,确保你的项目中包含了使用线程池所需的依赖。通常情况下,你可以使用SpringBoot来创建项目,它会自动包含......
  • nginx反向代理实现不同域名映射到同一台服务器的相同端口
    在实际应用中,我们经常会遇到多个域名需要映射到同一台服务器的相同端口的情况,这时可以使用nginx反向代理来实现。以实现将www.example.com和www.test.com都映射到127.0.0.1的80端口为例,具体步骤如下:修改hosts文件在本地hosts文件中添加以下两行:127.0.0.1www.example.com127.0.0.1......
  • 若依框架 前后端分离如何通过菜单管理添加菜单?
    1、创建主目录菜单,如图: 路由地址填写views下的文件名,目录结构参考如下:2、创建子菜单,点击新增 3、填写子菜单信息,参考如下: 路由地址填写:views下的二级文件夹名字组件路径填写为:views下到index.vue的路径(不要写文件后缀),例如:publish/mipsMaterialFiles/index权限字符......
  • 智能合约HardHat框架环境的搭建
    1.首先创建一个npm项目PSC:\Users\lcds\blockchainprojects>mkdirhardhatcontractPSC:\Users\lcds\blockchainprojects>cd.\hardhatcontract\2.运行 npminit-y  初始化项目PSC:\Users\lcds\blockchainprojects\hardhatcontract>npminit-yWrotetoC:\......