Hibernate中的多对多关联

2023-05-16

源自 imooc 的学习

       多对多关联是一种常见的关联关系。多对多关联关系一般采用中间表的形式来实现,即新增一张包含关联双方主键的关联表。那么,在Hibernate中如何实现多对多的关联关系呢?

       多对多关联可以使用<set>元素和<many-to-many>元素进行配置。具体如下:

1)需要在数据库底层通过添加中间表来指定关联关系;

2)在双方的实体中添加一个保存对方的集合;

3)在双方的映射文件中使用<set>元素和<many-to-many>元素进行关联关系的配置。

       以项目和员工的关系为例,一个项目可以有员工,一个员工可以参与多个项目,项目与员工是多对多的关系。

实现如下:

创建一个名为 hibernate-many2many 的项目,目录结构如下:

        首先在MySQL数据库中创建一个名为 hibernate2 的数据库,执行如下SQL语句,创建项目project 和 员工 employee表:

CREATE TABLE project (
  proid INT PRIMARY KEY ,
  proname VARCHAR (20) NOT NULL
);

CREATE TABLE employee (
  empid INT PRIMARY KEY ,
  empname VARCHAR (20)
);

CREATE TABLE proemp (
  rproid INT ,
  rempid INT
);

ALTER TABLE proemp ADD CONSTRAINT fk_rproid FOREIGN KEY (rproid) REFERENCES project(proid);
ALTER TABLE proemp ADD CONSTRAINT fk_rempid FOREIGN KEY (rempid) REFERENCES employee(empid);


       在 com.imooc.entity 包中创建Employee持久化类:

package com.imooc.entity;

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

/**
 * Created by DreamBoy on 2016/5/19.
 */

/**
 * 员工类
 */
public class Employee {
    private int empid;
    private String empname;
    //添加一个项目的集合
    private Set<Project> projects = new HashSet<Project>();

    public Employee() {
    }

    public Employee(int empid, String empname) {
        this.empid = empid;
        this.empname = empname;
    }

    public Employee(int empid, String empname, Set<Project> projects) {
        this.empid = empid;
        this.empname = empname;
        this.projects = projects;
    }

    public int getEmpid() {
        return empid;
    }

    public void setEmpid(int empid) {
        this.empid = empid;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }

    public Set<Project> getProjects() {
        return projects;
    }

    public void setProjects(Set<Project> projects) {
        this.projects = projects;
    }
}


       在com.imooc.entity 包中创建 Project持久化类:

package com.imooc.entity;

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

/**
 * Created by DreamBoy on 2016/5/19.
 */

/**
 * 项目类
 */
public class Project {
    private int proid;
    private String proname;
    //添加一个员工的集合
    private Set<Employee> employees = new HashSet<Employee>();

    public Project() {
    }

    public Project(int proid, String proname) {
        this.proid = proid;
        this.proname = proname;
    }

    public Project(int proid, String proname, Set<Employee> employees) {
        this.proid = proid;
        this.proname = proname;
        this.employees = employees;
    }

    public int getProid() {
        return proid;
    }

    public void setProid(int proid) {
        this.proid = proid;
    }

    public String getProname() {
        return proname;
    }

    public void setProname(String proname) {
        this.proname = proname;
    }

    public Set<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(Set<Employee> employees) {
        this.employees = employees;
    }
}


       在 com.imooc.entity 包中创建对应的映射配置文件:

Employee.hbm.xml

<?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="com.imooc.entity.Employee" table="employee">
        <id name="empid" column="empid" type="java.lang.Integer">
            <generator class="assigned"/>
        </id>
        <property name="empname" type="java.lang.String">
            <column name="empname" length="20" not-null="true"/>
        </property>
        <!-- 多对多关联关系 -->
        <set name="projects" table="proemp" inverse="true">
            <!-- 关联的外键 -->
            <key column="rempid"></key>
            <!-- 集合中关联的持久化类和外键 -->
            <many-to-many class="com.imooc.entity.Project" column="rproid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>


Project.hbm.xml

<?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="com.imooc.entity.Project" table="project">
        <id name="proid" column="proid" type="java.lang.Integer">
            <generator class="assigned"/>
        </id>
        <property name="proname" type="java.lang.String">
            <column name="proname" length="20" not-null="true"/>
        </property>
        <!-- 配置多对多关联关系 -->
        <set name="employees" table="proemp" cascade="all">
            <!-- 指定关联的外键列 -->
            <!-- 在关联表中项目的id,它是关联的外键 -->
            <key column="rproid"></key>
            <many-to-many class="com.imooc.entity.Employee" column="rempid"/>
        </set>
    </class>
</hibernate-mapping>

项目的配置文件 hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.username">root</property>
        <property name="connection.password"></property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 下面的 hibernate 指的是 数据库名,即所用的数据库 -->
        <property name="connection.url">jdbc:mysql:///hibernate2?useUnicode=true&characterEncoding=UTF-8</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="show_sql">true</property>
        <!--<property name="format_sql">true</property>-->
        <!--<property name="hbm2ddl.auto">create</property>-->
        <property name="hbm2ddl.auto">update</property>

        <!-- 指定映射文件的路径 -->
        <mapping resource="com/imooc/entity/Employee.hbm.xml"/>
        <mapping resource="com/imooc/entity/Project.hbm.xml"/>

        <!-- DB schema will be updated if needed -->
        <!-- <property name="hbm2ddl.auto">update</property> -->
    </session-factory>
</hibernate-configuration>


       在 com.imooc.test 包中创建 Test.java 测试类:

Test.java

package com.imooc.test;

/**
 * Created by DreamBoy on 2016/5/19.
 */

import com.imooc.entity.Employee;
import com.imooc.entity.Project;
import com.imooc.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

import java.io.Serializable;

/**
 * 多对多关联关系的配置
 * 同时建立了Project和Employee之间的双向多对多的关联关系
 *
 * 关联关系的维护?
 * 在 Employee.hbm.xml 的 set 节点中 inverse属性设置为true,
 * 表示关联关系的维护交由Project方来处理。
 *
 * 设置级联操作?
 * 保存project对象时,会自动保存project对象拥有的employ员工信息
 * 在 Project.hbm.xml 的 set 节点中 cascade属性设置为all,
 * 表示对project对象的所有操作都进行级联。
 *
 * 总结:
 * 关联关系的维护交由Project方来处理,并且在保存Project对象时会一并保存Employee对象。
 */
public class Test {
    public static void main(String[] args) {
        Project project1 = new Project(1001, "项目1");
        Project project2 = new Project(1002, "项目2");
        Employee employee1 = new Employee(1, "小小");
        Employee employee2 = new Employee(2, "小白");

        //参加项目1的员工有 employee1 和 employee2
        project1.getEmployees().add(employee1);
        project1.getEmployees().add(employee2);

        //参加项目2的员工有 employee1
        project2.getEmployees().add(employee1);

        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        //因为设置了级联操作,所以当保存project对象时,会自动级联保存对应所拥有的employee对象信息
        session.save(project1);
        session.save(project2);
        tx.commit();
        HibernateUtil.closeSession(session);

    }
}


运行结果如下:





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate中的多对多关联 的相关文章

随机推荐

  • 网页中时光轴的简单实现

    时光轴效果如下 xff1a 鼠标滑过当前项时 xff0c 左侧图标大小变大 xff1a index html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta
  • 伸缩自如的时光轴实现

    上回说到简单时间轴的实现 xff0c 这一次针对上回的实现的时光轴 xff0c 增加时光轴收起的功能 为了方便重用 xff0c 我分离css样式和js 使用过程中主要注意一下尽量使用css定义的时光轴样式即可 时光轴收起功能的实现过程可以查
  • 伸缩自如的时光轴实现——改进版

    上回讲到的是时光轴 伸缩自如 的实现 xff0c 如果基于响应式制作的话 xff0c 可能存在着许多潜在的BUG 如 xff1a 窗口变化时 xff0c 时光轴的 收起 和 展开 xff0c 都发生了一些变形 为此 xff0c 对原来的 t
  • 伸缩自如的时光轴实现_样式改版

    针对前几篇文章中实现的 伸缩自如 的时光轴 xff0c 对时光轴的样式进行又一次修改 xff0c 效果如下 xff1a 点击 收起 后 xff1a 修改后的 timeline css xff0c 如下 xff1a vertical time
  • ThinkPHP中的create方法与自动令牌验证

    转载自 xff1a Thinkphp中Create方法深入探究 ThinkPHP中的create方法与自动令牌验证实例教程 Thinkphp中Create方法深入探究 由于工作原因在thinkPHP的create 方法上遇到了问题 xff0
  • web安全之token和CSRF攻击

    上文我转载了两篇关于ThinkPHP令牌验证的文章 xff08 ThinkPHP中的create方法与自动令牌验证 xff09 其中提及到了 token xff0c 这里针对 token 的作用 xff0c 转载了另外两篇文章 xff08
  • java中的==、equals和hashCode以及hashCode生成

    转载自 xff1a xff08 点击打开链接 xff09 前言 java中 61 61 equals hashCode 都和对象的比较有关 xff0c 在java中这三者各有什么用处呢 xff0c 即java中为什么需要设计这三种对象的比较
  • javascript调用微信或QQ扫一扫

    项目里为了体验做的好点 xff0c 想直接通过js调用手机的扫一扫 xff1a 服务的用户主要是通过 xff1a 微信或QQ 之前使用过 微信或QQ的分享 腾讯移动WEB开发平台的 39 对外分享组件接口文档 39 http open mo
  • Java中的反射机制

    获取类的类类型的3种方式 xff0c 以及如何通过类的类类型创建实例对象 xff1f ClassDemo1 java package com reflect public class ClassDemo1 public static voi
  • Java中的自定义注解

    自定义注解 Description java xff08 这里自定义Description注解 xff09 package com ann test import java lang annotation Documented import
  • Java中自定义注解的应用

    来自 慕课网 的学习 我们可以使用自定义注解 xff0c 实现ORM xff0c 即对象 关系的映射 通过自定义注解 xff0c 定义对象对应数据表的属性 xff0c 如表名 xff0c 表字段等 Table java xff08 Tabl
  • Intellij IDEA下的第一个Hibernate项目

    参考 xff1a intellij配置hibernate自动生成hbm xml文件 从零开始用Intellij idea14创建hibernate项目 下面我要讲的创建方式 xff0c 可能更加原生态 xff0c 更加类似于Eclipse下
  • Intellij IDEA使用注解创建Hibernate项目中的OR映射类

    上回说到 xff1a Intellij IDEA下的第一个Hibernate项目 我们需要创建 对象到关系的映射配置文件 xff0c 如 entity hbm xml xff08 其中 entity 是我们将要创建的实体 xff09 下面讲
  • Hibernate中Blob对象类型的使用

    使用Intellij IDEA创建Hibernate项目 xff0c 目录结构如下 xff1a 其中 assets app png 为将要存储的照片 xff0c src hibernate cfg xml 为Hibernate的配置文件 x
  • Hibernate组件映射

    转载自 xff1a 点击打开链接 在Hibernate中 component 是某个实体的逻辑组成部分 xff0c 它与实体的根本区别是没有oid xff08 对象标识符 xff09 xff0c component是一个被包含的对象 它作为
  • Hibernate中的单向一对多关联

    源自 imooc 中的学习 Hibernate中的单向一对多关联 xff0c 这里举例 班级对学生 的单向一对多关联 xff0c 即一个班级可以有多个学生 那么在Hibernate中实体对象间如何体现出单向一对多的关联关系呢 xff1f 如
  • Hibernate中的单向多对一关联

    继上回讲到 Hibernate中的单向一对多关联 xff0c 这次来实现一下Hibernate中的单向多对一关联 对原来的项目修改如下 xff1a Hibernate中的单向多对一关联 xff0c 需要我们在多方增加一个一方的属性 xff0
  • Hibernate中的双向多对一关联以及 inverse属性、cascade属性的用法

    上回 说了 Hibernate中的单向一对多关联 和 Hibernate中的单向多对一关联 这次针对这两个 单向 进行整合即可实现双向的多对一关联 如 xff1a 学生与班级的关系 在Grade类中需要添加 Set集合保存Student对象
  • 优化器 optimizer

    优化器 optimizer optimizer 优化器 xff0c 用来根据参数的梯度进行沿梯度下降方向进行调整模型参数 xff0c 使得模型loss不断降低 xff0c 达到全局最低 xff0c 通过不断微调模型参数 xff0c 使得模型
  • Hibernate中的多对多关联

    源自 imooc 的学习 多对多关联是一种常见的关联关系 多对多关联关系一般采用中间表的形式来实现 xff0c 即新增一张包含关联双方主键的关联表 那么 xff0c 在Hibernate中如何实现多对多的关联关系呢 xff1f 多对多关联可