Hibernate学习笔记(八):多对多映射

需求:项目 和 开发人员;

一个项目可以有多个开发人员,一个开发人员也可以参加多个项目,这种映射关系叫做 多对多映射。

项目结构:

项目实体类 Project.java:

package com.hibernate.many2many;

import java.util.Set;

/**
 * 项目实体类
 */
public class Project {
    private int pro_id;
    private String pro_name;
    private Set<Developer> developers; // 一个项目可以对应多个开发人员

    public int getPro_id() {
        return pro_id;
    }

    public void setPro_id(int pro_id) {
        this.pro_id = pro_id;
    }

    public String getPro_name() {
        return pro_name;
    }

    public void setPro_name(String pro_name) {
        this.pro_name = pro_name;
    }

    public Set<Developer> getDevelopers() {
        return developers;
    }

    public void setDevelopers(Set<Developer> developers) {
        this.developers = developers;
    }
}

开发者实体类 Developer.java:

package com.hibernate.many2many;

import java.util.Set;

/**
 * 开发者实体类
 */
public class Developer {
    private int dev_id;
    private String dev_name;
    private Set<Project> projects; // 一个开发人员可以对应多个项目

    public int getDev_id() {
        return dev_id;
    }

    public void setDev_id(int dev_id) {
        this.dev_id = dev_id;
    }

    public String getDev_name() {
        return dev_name;
    }

    public void setDev_name(String dev_name) {
        this.dev_name = dev_name;
    }

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

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

项目配置文件 Project.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- 项目配置文件 -->
<hibernate-mapping package="com.hibernate.many2many">
	<class name="Project" table="t_project">
		<!-- 主键映射 -->
		<id name="pro_id" column="pro_id">
			<generator class="native"/>
		</id>
		<!-- 普通字段映射 -->
		<property name="pro_name"/>

		<!--
			多对多映射:
		 	name="developers":指定映射的集合属性;
			table="t_relation":集合属性对应的中间表;
			column="pro_id":当前对象在 中间表中的 外键字段;
			class="Developer":集合属性 元素的类型(开发者对象);
			column="dev_id":当前对象在 中间表中 对应 开发者对象的 外键字段;
			cascade:级联操作
				none:默认值,表示不级联操作;
				save-update:表示级联保存和修改,即保存和修改项目表中的数据时,会自动保存和修改相关联的 开发者表中的数据;
				delete:级联删除,当删除项目表中的数据时,会自动删除相关联的开发者表中的数据;
				all:所有操作都级联
		-->
		<set name="developers" table="t_relation" cascade="save-update">
			<key column="pro_id"/>
			<many-to-many class="Developer" column="dev_id"/>
		</set>
	</class>
</hibernate-mapping>

开发者配置文件 Developer.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- 开发者配置文件 -->
<hibernate-mapping package="com.hibernate.many2many">
	<class name="Developer" table="t_developer">
		<!-- 主键映射 -->
		<id name="dev_id" column="dev_id">
			<generator class="native"/>
		</id>
		<!-- 普通字段映射 -->
		<property name="dev_name"/>

		<!--
			多对多映射:
			name="projects":指定映射的集合属性
			table="t_relation":集合属性对应的中间表
			column="dev_id":当前对象在 中间表中的 外键字段
			class="Project":集合属性 元素的类型(项目对象)
			column="pro_id":当前对象在 中间表中 对应的 项目对象的 外键字段
		-->
		<set name="projects" table="t_relation">
			<key column="dev_id"/>
			<many-to-many class="Project" column="pro_id"/>
		</set>
	</class>
</hibernate-mapping>

主配置文件 hibernate.cfg.xml:

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<!-- 数据库配置 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql:///hib_demo</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

		<!-- 显示 sql 语句 -->
		<property name="hibernate.show_sql">true</property>

		<!-- 如果表不存在,则自动建表;如果表已存在,则更新表; -->
		<property name="hibernate.hbm2ddl.auto">update</property>
	</session-factory>
</hibernate-configuration>

测试程序 Demo.java:

package com.hibernate.many2many;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

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

public class Demo {

    private static SessionFactory sessionFactory;
    static {
        // 加载主配置文件,自动加载映射文件,创建 session 工厂
        sessionFactory = new Configuration()
                .configure()
                .addClass(Developer.class)
                .addClass(Project.class)
                .buildSessionFactory();
    }

    @Test
    public void test1(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        // 创建项目对象
        Project project1 = new Project();
        project1.setPro_name("电商系统");

        Project project2 = new Project();
        project2.setPro_name("OA系统");

        // 创建开发者对象
        Developer developer1 = new Developer();
        developer1.setDev_name("张三");

        Developer developer2 = new Developer();
        developer2.setDev_name("李四");

        Developer developer3 = new Developer();
        developer3.setDev_name("王五");

        // 假设 张三、李四 参加了 电商系统,那么将 张三、李四 添加到一个 set 集合中
        Set<Developer> developers1 = new HashSet<>();
        developers1.add(developer1);
        developers1.add(developer2);

        // 假设 李四、王五 参加了 OA 系统,那么将 李四、王五 添加到一个 set 集合中
        Set<Developer> developers2 = new HashSet<>();
        developers2.add(developer2);
        developers2.add(developer3);

        // 关联关系:通过项目对象 维护开发者对象
        project1.setDevelopers(developers1); // 电商系统维护的开发人员为 张三和李四
        project2.setDevelopers(developers2); // OA 系统维护的开发人员为 李四和王五

        // 保存:因为 项目配置文件(Project.hbm.xml) 中配置了 级联保存和修改,
        // 所以保存 项目数据时,会自动保存 相关联的开发者数据
        session.save(project1);
        session.save(project2);

        transaction.commit();
        session.close();
    }
}

结果:

inverse 控制反转对 多对多维护关联关系的影响:

1、保存数据:

有影响;

inverse = "false",有控制权,可以维护关联关系:保存数据的时候会把对象关系插入中间表;

inverse = "true",没有控制权,不能维护关联关系:即不会往中间表插入数据;

2、获取数据:

没有影响;

3、解除关联关系:

有影响;

inverse = "false",有控制权,解决关系就是删除中间表的数据;

inverse = "true",没有控制权,不能解除关系;

4、删除数据:

有影响;

inverse = "false",有控制权,先删除中间表数据,在删除自身;

inverse = "true",没有控制权,如果删除的数据有被外键引用,会报错;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值