双向多对多inverse配置

如果关系两边都使用默认inverse=false配置,表示关系两边都可以管理中间表的数据

关系其中一边设置inverse=true配置,表示自己放弃管理中间表关系,由对方来管理

如果关系两边都使用默认inverse=true配置,表示关系两边都不管理中间表,是不能这样配置的

hibernate.cfg.xml

<mapping resource="com/jege/hibernate/two/way/manytomany/User.hbm.xml" />
<mapping resource="com/jege/hibernate/two/way/manytomany/Role.hbm.xml" />

User.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.jege.hibernate.two.way.manytomany">
<class name="User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<!-- 配置中间表t_user_role -->
<set name="roles" table="t_user_role">
<!-- 配置当前类User在中间表的主外键名称 -->
<key column="user_id" />
<!-- 多对多 -->
<!-- class必须配置, column配置关联类Role在中间表的主外键名称 -->
<many-to-many class="Role" column="role_id" />
</set>
</class>
</hibernate-mapping>

Role.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.jege.hibernate.two.way.manytomany">
<class name="Role" table="t_role">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<!-- 配置中间表t_user_role -->
<set name="users" table="t_user_role">
<!-- 配置当前类Role在中间表的主外键名称 -->
<key column="role_id" />
<!-- 多对多 -->
<!-- class必须配置, column配置关联类User在中间表的主外键名称 -->
<many-to-many class="User" column="user_id" />
</set>
</class>
</hibernate-mapping>

Role

private Long id;
private String name;
private Set<User> users = new HashSet<User>();

User

private Long id;
private String name;
private Set<Role> roles = new HashSet<Role>();

CrudTest

package com.jege.hibernate.two.way.manytomany;

import org.hibernate.Session;
import org.junit.Before;
import org.junit.Test; import com.jege.hibernate.two.way.manytomany.Role;
import com.jege.hibernate.two.way.manytomany.User;
import com.jege.hibernate.util.HibernateUtils; /**
* @author JE哥
* @email 1272434821@qq.com
* @description:多对多的处理
*/
public class CrudTest { // 保存2个用户,保存3个角色(会出现5条insert语句)
// 保存中间表:建立用户到角色关系jegeUser1(jegeRole1,jegeRole2),jegeUser2(jegeRole1,jegeRole2,jegeRole3)(会出现5条insert语句)
// 一般保存的:需要写5个save方法
@Before
public void save() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
// 保存2个用户,保存3个角色(会出现5条insert语句)
User jegeUser1 = new User("jegeUser1");
session.save(jegeUser1);
User jegeUser2 = new User("jegeUser2");
session.save(jegeUser2); Role jegeRole1 = new Role("jegeRole1");
session.save(jegeRole1);
Role jegeRole2 = new Role("jegeRole2");
session.save(jegeRole2);
Role jegeRole3 = new Role("jegeRole3");
session.save(jegeRole3);// (这里的5个save方法会出现5条insert语句) // 保存中间表:建立用户到角色关系jegeUser1(jegeRole1,jegeRole2),jegeUser2(jegeRole1,jegeRole2,jegeRole3)
jegeUser1.getRoles().add(jegeRole1);
jegeUser1.getRoles().add(jegeRole2); jegeUser2.getRoles().add(jegeRole1);
jegeUser2.getRoles().add(jegeRole2);
jegeUser2.getRoles().add(jegeRole3);
jegeUser2.getRoles().add(jegeRole3); session.getTransaction().commit();// 事务里面,更新脏数据(会出现5条insert语句)
session.close();
} // 删除jegeUser1(由hibernate自动处理,流程是先删除中间表,在删除jegeUser1)
@Test
public void delete1() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
User jegeUser = (User) session.get(User.class, 1L); session.beginTransaction();
session.delete(jegeUser);
session.getTransaction().commit(); session.close();
} // 删除jegeUser1的关联的角色(中间表),实现不能删除jegeUser1
@Test
public void delete2() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
User jegeUser = (User) session.get(User.class, 1L); session.beginTransaction();
jegeUser.getRoles().clear();
session.getTransaction().commit(); session.close();
} // 删除jegeUser1的一个角色,实现不能删除jegeUser1
@Test
public void delete3() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
User jegeUser = (User) session.get(User.class, 1L);
Role jegeRole = (Role) session.get(Role.class, 1L); session.beginTransaction();
jegeUser.getRoles().remove(jegeRole);
session.getTransaction().commit(); session.close();
} // 修改角色:先删除jegeUser1.jegeRole2,在添加jegeUser1.jegeRole3
// 关系jegeUser1(jegeRole1,jegeRole2)变为关系jegeUser1(jegeRole1,jegeRole3)
@Test
public void update() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
User jegeUser = (User) session.get(User.class, 1L);
Role jegeRole2 = (Role) session.get(Role.class, 2L);
Role jegeRole3 = (Role) session.get(Role.class, 3L); session.beginTransaction();
jegeUser.getRoles().remove(jegeRole2);
jegeUser.getRoles().add(jegeRole3);
session.getTransaction().commit(); session.close();
} }

源码地址

https://github.com/je-ge/hibernate

如果觉得我的文章对您有帮助,请予以打赏。您的支持将鼓励我继续创作!谢谢!



Hibernate 系列教程6-双向多对多的更多相关文章

  1. Hibernate 系列教程5-双向多对一

    主要讲解inverse和cascade的用法 cascade定义的是关系两端对象到对象的级联关系: 而inverse定义的是关系和对象的级联关系(管理外键的值). inverse 属性默认是false ...

  2. Hibernate 系列教程4-单向多对一

    项目图片 hibernate.cfg.xml <mapping resource="com/jege/hibernate/one/way/manytoone/User.hbm.xml& ...

  3. JPA 系列教程7-双向多对多

    双向多对多的ddl语句 同单向多对多表的ddl语句一致 Student package com.jege.jpa.many2many; import java.util.HashSet; import ...

  4. JPA 系列教程3-单向多对一

    JPA中的@ManyToOne 主要属性 - name(必需): 设定"many"方所包含的"one"方所对应的持久化类的属性名 - column(可选): 设 ...

  5. Hibernate 系列教程16-二级缓存

    pom.xml <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate- ...

  6. Hibernate 系列教程9-自关联

    自关联:本质还是原来双向一对多,原来要配置两个类,现在全部都配置在一个类里面 Employee public class Employee { private Long id; private Str ...

  7. Hibernate 系列教程7-双向一对一

    双向一对一 一对一主要用在 一个一方需要的信息比较少,比如注册的登录信息 另一个一方存储的信息比较多,比如注册之后用户填写的详细信息 实现方式常用的主要有2种: java模型都是一样,其中一个映射文件 ...

  8. JPA 系列教程6-单向多对多

    JPA中的@ManyToMany @ManyToMany注释表示模型类是多对多关系的一端. @JoinTable 描述了多对多关系的数据表关系. name 属性指定中间表名称 joinColumns ...

  9. Hibernate 系列教程17-查询缓存

    在二级缓存配置成功的基础上进行查询缓存配置 Product public class Product { private Long id; private String name; Product.h ...

随机推荐

  1. JS的异步回调函数

    hi :)几日不见,趁着周末和父母在广州走走逛逛,游山玩水,放松身心,第一天上班就被一个问题难住了,不废话,以下是关于JS函数回调方面的知识,今天的查阅看的也是一知半解,摘录下来日后慢慢琢磨! js中 ...

  2. 【Sort】HeapSort

    堆排序,时间复杂度O(N log N),实际使用中慢于使用Sedgewick增量的增量排序. 大致思路: 1.先在数组中建堆,如果是增量排序,则需要建一个大堆 2.每循环一次,把最大的数,也就是num ...

  3. bzoj1336: [Balkan2002]Alien最小圆覆盖

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1336 1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 ...

  4. JS计算字符串长度(中文算2个)

    /** * @return {number} */ getRealLength = function(str) { var realLength = 0, len = str.length, char ...

  5. 带密钥的sha1加密

    带密钥的sha1加密: private static string HmacSha1Sign(string jsonStr, string secretKey, string enCoding ) { ...

  6. jquery.validate.js 无法验证隐藏域

    隐藏域中的字段无法验证解决办法 修改 jquery.validate.js 中的 ignore: ":hidden",

  7. 不要在 _ASSERT() 宏中执行功能代码 AND RELEASE版调试办法

            程序在DEBUG版正常运行,在RELEASE版就崩溃了,想调试找问题,却发现RELEASE版根本走不到断点... 需要在工程配置中将 Configuration Properties- ...

  8. Linux下好用的简单实用命令

    1.你是否为在输入了一大串命令之后发现第一个字符打错了而苦恼?只能删除重来嘛?或者一步步左移光标? NO,一个组合键轻松搞定 Ctrl+A -----到命令行首 Ctrl+E ------到命令行末 ...

  9. 设M=5^2003+7^2004+9^2005+11^2006,求证8|M。(整除理论,1.1.8)

    设M=52003+72004+92005+112006,求证8|M. 证明: 前提:对于,52003让我们去构造8,即用8-3替换5 第一步:用8-3替换5,且仅替换一个, 第二步:进行分项,则前一项 ...

  10. ural 1353. Milliard Vasya's Function(dp)

    1353. Milliard Vasya's Function Time limit: 1.0 second Memory limit: 64 MB Vasya is the beginning ma ...