多对多的映射关系和级联

开发步骤:

创建表

 用户表
CREATE TABLE sys_user (
user_id bigint(32) NOT NULL AUTO_INCREMENT COMMENT ‘用户id’,
user_code varchar(32) NOT NULL COMMENT ‘用户账号’,
user_name varchar(64) NOT NULL COMMENT ‘用户名称’,
user_password varchar(32) NOT NULL COMMENT ‘用户密码’,
user_state char(1) NOT NULL COMMENT ‘1:正常,0:暂停’,
PRIMARY KEY (user_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
角色表
CREATE TABLE sys_role (
role_id bigint(32) NOT NULL AUTO_INCREMENT,
role_name varchar(32) NOT NULL COMMENT ‘角色名称’,
role_memo varchar(128) DEFAULT NULL COMMENT ‘备注’,
PRIMARY KEY (role_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
中间表
CREATE TABLE sys_user_role (
role_id bigint(32) NOT NULL COMMENT ‘角色id’,
user_id bigint(32) NOT NULL COMMENT ‘用户id’,
PRIMARY KEY (role_id,user_id),
KEY FK_user_role_user_id (user_id),
CONSTRAINT FK_user_role_role_id FOREIGN KEY (role_id) REFERENCES sys_role (role_id) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT FK_user_role_user_id FOREIGN KEY (user_id) REFERENCES sys_user (user_id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建实体

用户的实体
public class User {
private Long user_id;
private String user_code;
private String user_name;
private String user_password;
private String user_state;

private Set<Role> roles = new HashSet<Role>();

角色的实体
public class Role {
private Long role_id;
private String role_name;
private String role_memo;

private Set<User> users = new HashSet<User>();

1.3.1.3创建映射
用户的映射

《class name=“com.yidongxueyuan.mapping.User” table=“sys_user”> id
name=“user_id” column=“user_id”> generator class=“native”/> /id>
property name=“user_code” column=“user_code”/> property
name=“user_name” column=“user_name”/> property name=“user_password”
column=“user_password”/> property name=“user_state”
column=“user_state”/>

	<!-- 创建和角色的关系:
	 name:对象的集合的属性的名称:
	 table; 多对多的关系 , 需要使用中间表, 引入的中间表的名称
	 -->
	<set name="roles" table="sys_user_role">
		<!-- 
			key: 标签: 
			column: 当前对象, 对应中间表的外键的名称:
		 -->
		<key column="user_id"/>
		<!-- 
			class: 对方类的全路径名称: 
			column: 对方的对象在中间表的外键名称:
		 -->
		<many-to-many class="com.yidongxueyuan.mapping.Role" column="role_id"/>
	</set>
</class>

角色的映射

class name=“com.yidongxueyuan.mapping.Role” table=“sys_role”> id
name=“role_id” column=“role_id”> generator class=“native”/>
property name=“role_name” column=“role_name”/> property
name=“role_memo” column=“role_memo”/>

	<!-- 创建和角色的关系:
	 name:对象的集合的属性的名称:
	 table; 多对多的关系 , 需要使用中间表, 引入的中间表的名称
	 -->
	<set name="users" table="sys_user_role" inverse="true">
		<!-- 
			key: 标签: 
			column: 当前对象, 对应中间表的外键的名称:
		 -->
		<key column="role_id"/>
		<!-- 
			class: 对方类的全路径名称: 
			column: 对方的对象在中间表的外键名称:
		 -->
		<many-to-many class="com.yidongxueyuan.mapping.User" column="user_id"/>
	</set>
</class>

编写测试类

/*

  • 测试多对多:
    */
    public class HibernateManyToMany {

    @Test
    public void test01() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

     //创建一个2个用户: 
     User user1 = new User();
     user1.setUser_name("毕老师");
     
     User user2 = new User();
     user2.setUser_name("张老师");
     
     
     //创建三个角色: 
     Role role1= new Role();
     role1.setRole_name("市场部");
     
     Role role2= new Role();
     role2.setRole_name("研发部");
     
     Role role3= new Role();
     role3.setRole_name("人资部");
     
     //设置双向关联关系:
     user1.getRoles().add(role1);// 1 2 角色: 
     user1.getRoles().add(role2);// 1 2 角色: 
     user2.getRoles().add(role2);// 2 3 Juese
     user2.getRoles().add(role3);// 2 3 Juese
     
     role1.getUsers().add(user1);
     role2.getUsers().add(user1);
     role2.getUsers().add(user2);
     role3.getUsers().add(user2);
     
     //保存操作: 
     /*
      * 问题:如果设置了双向维护: 两个表都有权利维护第三种表: 会出现主键冲突问题:
      * org.hibernate.exception.ConstraintViolationException: 
      * could not execute statement
      * 
      * 解决: 必须一方放弃外键的维护: 
      * 通常设置被动方放弃一方放弃维护外键。  被选择的一方: ;role
      * 在role当中的配置文件当中: inverse="true"
      */
     session.save(user1);
     session.save(user2);
     session.save(role1);
     session.save(role2);
     session.save(role3);
     
     tx.commit();
    

    }
    }

Hibernate的多对多的操作

只保存一边是否可以
/*
* 测试: 值保存一方是否可以?
* 经过测试: 不可以, 同样的会抛出一个异常。
* 一个持久对象关联了一个瞬时对象。
* 解决: 设置级联操作:
*/
@Test
public void test02() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

	User user1 = new User();
	user1.setUser_name("毕老师");
	
	Role role1= new Role();
	role1.setRole_name("市场部");
	
	//设置双向关联关系:
	user1.getRoles().add(role1);// 1 2 角色: 
	role1.getUsers().add(user1);
	

	session.save(user1);

// session.save(role1);
tx.commit();
}
1.3.2.2多对多的级联保存或更新
保存用户级联保存角色

保存角色级联保存用户

1.3.2.3多对多的级联删除(基本用不上)
删除用户级联删除角色

删除角色级联删除用户

1.3.2.4多对多的其他的操作
给用户选择角色

给用户改选角色

给用户删除角色

还是放一个多对多的例子吧233333333333333

package com.yidongxueyuan.test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.yidongxueyuan.mapping.Role;
import com.yidongxueyuan.mapping.User;
import com.yidongxueyuan.utils.HibernateUtils;

public class HibernateManyToMany {
	public static void main(String[] args) {
		//保存操作: 
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		//准备数据:  用户数据: 
		User user = new User(); 
		user.setUser_name("bi1");
		
		User user2 = new User(); 
		user2.setUser_name("he2");
		
		//准备角色数据: 
		Role role1= new Role(); 
		role1.setRole_name("普通用户");
		
		
		Role role2= new Role(); 
		role2.setRole_name("会员用户");
		
		Role role3= new Role(); 
		role3.setRole_name("管理员");
		
		//建立双方之间的关系: 
		user.getRoles().add(role1);
		user.getRoles().add(role2);
		
		user2.getRoles().add(role2);
		user2.getRoles().add(role3);
		
		role1.getUsers().add(user);
		role2.getUsers().add(user);
		
		role2.getUsers().add(user2);
		role3.getUsers().add(user2);
		
		//保存: 
		session.save(user);
		session.save(user2);
		
		session.save(role1);
		session.save(role2);
		session.save(role3);
		
		//运行结果: Duplicate entry '1-1' for key 'PRIMARY' 出现了异常: 
		//原因: user 和 role 都维护了映射表: 
		//解决: 是的一方放弃外键的维护全: 
		/*
		 * 被动方放弃外键维护: 
		 */
		
		tx.commit();
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方-教育技术博主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值