详解hibernate双向多对多关联映射XML与注解版

双向多对多关联映射原理:

假设,一个员工可能有多个角色,一个角色可能有多个员工,从员工或角色的角度看,这就是多对多的关系,不管从哪一个角度看,都是多对多的联系。多对多关联映射关系一般采用中间表的形式来实现,即新增一种包含关联双方主键的表。实现多对多关联关系,在数据库底层通过添加中间表指定关联关系,而在hibernate框架在双方的实体中添加一个保存对方的集合,在双方的映射文件中使用<set>元素和<many-to-many>元素进行关联关系的配置。

如下图所示:

(1)XML版

Role类:

package Hibernate_demo1.Demo15.Entity; 

import java.util.Set; 

public class Role { 

  private String id;
  private String rame;
  private Set<User> users; 

  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public String getRame() {
    return rame;
  }
  public void setRame(String rame) {
    this.rame = rame;
  }
  public Set<User> getUsers() {
    return users;
  }
  public void setUsers(Set<User> users) {
    this.users = users;
  }
}

User类:

package Hibernate_demo1.Demo15.Entity; 

import java.util.Set; 

public class User { 

  private String id;
  private String uname;
  private Set<Role> roles; 

  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public String getUname() {
    return uname;
  }
  public void setUname(String uname) {
    this.uname = uname;
  }
  public Set<Role> getRoles() {
    return roles;
  }
  public void setRoles(Set<Role> roles) {
    this.roles = roles;
  } 

}

Role.hbm.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="Hibernate_demo1.Demo15.Entity.Role" table="role">
    <id name="id" type="java.lang.String">
      <column name="id"/>
      <generator class="uuid">
      </generator>
    </id>
    <property name="rame" column="rname"/> 

    <set name="users" table="user_role">
      <key column="roleid"></key>
      <many-to-many class="Hibernate_demo1.Demo15.Entity.User" column="userid"></many-to-many>
    </set>
  </class>
</hibernate-mapping>

User.hbm.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="Hibernate_demo1.Demo15.Entity.User" table="user">
    <id name="id">
      <generator class="uuid">
      </generator>
    </id>  

    <property name="uname" column="uname"/>  

     <set name="roles" table="user_role">
      <key column="userid"/>
      <many-to-many class="Hibernate_demo1.Demo15.Entity.Role" column="roleid" />
    </set>
  </class>
</hibernate-mapping>

测试类:

package Hibernate_demo1.Demo15; 

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

import org.hibernate.Session; 

import Hibernate_demo1.Demo15.Entity.Role;
import Hibernate_demo1.Demo15.Entity.User;
import Hibernate_demo1.Demo15.Util.HibernateUtils; 

public class App
{
  public static void main( String[] args )
  { 

    Session session = null;
    try{  

      session = HibernateUtils.getSession();
      session.beginTransaction();  

      Role r1 = new Role();
      r1.setRame("数据录入人员");
      session.save(r1); 

      Role r2 = new Role();
      r2.setRame("商务主管");
      session.save(r2); 

      Role r3 = new Role();
      r3.setRame("商务经理");
      session.save(r3); 

      Role r4 = new Role();
      r4.setRame("项目会计");
      session.save(r4); 

      User u1 = new User();
      u1.setUname("张三");
      Set<Role> u1Roles = new HashSet<Role>();
      u1Roles.add(r1);
      u1Roles.add(r2);
      u1.setRoles(u1Roles);
      session.save(u1); 

      User u2 = new User();
      u2.setUname("李四");
      Set<Role> u2Roles = new HashSet<Role>();
      u2Roles.add(r1);
      u2Roles.add(r2);
      u2Roles.add(r3);
      u2.setRoles(u2Roles);
      session.save(u2); 

      User u3 = new User();
      u3.setUname("王五");
      Set<Role> u3Roles = new HashSet<Role>();
      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);
    }
  }
}

执行结果:

Hibernate:
  insert
  into
    role
    (rname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    role
    (rname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    role
    (rname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    role
    (rname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    user
    (uname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    user
    (uname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    user
    (uname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)

数据库内容为:

user表:

role表:

user_role表:

(2)注解版

Role类:

package Hibernate_demo1.Demo16.Entity; 

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

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table; 

import org.hibernate.annotations.GenericGenerator; 

@Entity
@Table(name="role")
public class Role { 

  @Id
    @GenericGenerator(name="uuidGenerator", strategy="uuid")
    @GeneratedValue(generator="uuidGenerator")
  private String id; 

  @Column(name="rname")
  private String rame; 

  @ManyToMany(cascade=CascadeType.REFRESH,mappedBy="roles")
  private Set<User> users=new HashSet<User>(); 

  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public String getRame() {
    return rame;
  }
  public void setRame(String rame) {
    this.rame = rame;
  }
  public Set<User> getUsers() {
    return users;
  }
  public void setUsers(Set<User> users) {
    this.users = users;
  }
}

User类:

package Hibernate_demo1.Demo16.Entity; 

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

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.JoinColumn; 

import org.hibernate.annotations.GenericGenerator; 

@Entity
@Table(name="user")
public class User { 

  @Id
    @GenericGenerator(name="uuidGenerator", strategy="uuid")
    @GeneratedValue(generator="uuidGenerator")
  private String id; 

  @Column(name="uname")
  private String uname; 

  /*
   * @ManyToMany表示多对多关联,对于这种关联极少数情况会使用级联删除,我这里设置的是级联刷新;
   * 因为有中间表的存在这里使用@JoinTable来设置关联表后面的name配置的是关联表的名称
   * inverseJoinColumn配置的是关系被维护一方主键对应的中间表字段
   * joinColumn配置的是关系维护方主键对应的中间表字段。
   */
  @ManyToMany(cascade=CascadeType.REFRESH)
  @JoinTable(name="user_role",inverseJoinColumns=@JoinColumn(name="roleid"),joinColumns=@JoinColumn(name="userid"))
  private Set<Role> roles=new HashSet<Role>(); 

  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public String getUname() {
    return uname;
  }
  public void setUname(String uname) {
    this.uname = uname;
  }
  public Set<Role> getRoles() {
    return roles;
  }
  public void setRoles(Set<Role> roles) {
    this.roles = roles;
  } 

}

测试类:

package Hibernate_demo1.Demo16; 

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

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; 

import Hibernate_demo1.Demo16.Entity.Role;
import Hibernate_demo1.Demo16.Entity.User; 

public class Test { 

  public static void main(String[] args) { 

    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.getCurrentSession();
    Transaction tx = session.beginTransaction();  

    //创建两个用户
    User us1=new User();
    us1.setUname("小明"); 

    User us2=new User();
    us2.setUname("小黑"); 

    //创建用户集合
    Set<User> su=new HashSet<User>();
    su.add(us1);
    su.add(us2); 

    //创建两个角色
    Role ro1=new Role();
    ro1.setRame("程序员");
    ro1.setUsers(su); 

    Role ro2=new Role();
    ro2.setRame("技术经理");
    ro2.setUsers(su); 

    //创建角色集合
    Set<Role> sr=new HashSet<Role>();
    sr.add(ro1);
    sr.add(ro2); 

    //往用户添加角色集合
    us1.setRoles(sr);
    us2.setRoles(sr); 

    //保存用户和角色
    session.save(us1);
    session.save(us2);
    session.save(ro1);
    session.save(ro2); 

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

}

执行结果如下:

Hibernate:
  insert
  into
    user
    (uname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    user
    (uname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    role
    (rname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    role
    (rname, id)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)
Hibernate:
  insert
  into
    user_role
    (userid, roleid)
  values
    (?, ?)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Eclipse添加xml文件提示及Hibernate配置学习

    添加Hibernate配置文件提示 解压hibernate.jar包 在org\hibernate目录下找到hibernate-configuration-3.0.dtd和hibernate-mapping-3.0.dtd 打开Eclipse-->Window-->Preferences-->Web and XML-->XML Catalog 在右边点击Add XML Catalog Entry location:引入上面说的dtd文件 Key Type:URL Key:打开dtd

  • Hibernate使用hbm.xml配置映射关系解析

    在使用hibernate时,经常需要配置与类对应的hbm.xml文件,并在其中指明数据库表的具体细节. 由于映射关系的配置比较繁琐,故总结了模板代码如下: 多对一: <many-to-one name="本类中的属性名" class="对方类" column="本类中的属性名+Id"></many-to-one> 一对多: <set name="本类中的属性名"> <key colum

  • 详解hibernate双向多对多关联映射XML与注解版

    双向多对多关联映射原理: 假设,一个员工可能有多个角色,一个角色可能有多个员工,从员工或角色的角度看,这就是多对多的关系,不管从哪一个角度看,都是多对多的联系.多对多关联映射关系一般采用中间表的形式来实现,即新增一种包含关联双方主键的表.实现多对多关联关系,在数据库底层通过添加中间表指定关联关系,而在hibernate框架在双方的实体中添加一个保存对方的集合,在双方的映射文件中使用<set>元素和<many-to-many>元素进行关联关系的配置. 如下图所示: (1)XML版 R

  • 详解SpringBoot 快速整合Mybatis(去XML化+注解进阶)

    序言:使用MyBatis3提供的注解可以逐步取代XML,例如使用@Select注解直接编写SQL完成数据查询,使用@SelectProvider高级注解还可以编写动态SQL,以应对复杂的业务需求. 一. 基础注解 MyBatis 主要提供了以下CRUD注解: @Select @Insert @Update @Delete 增删改查占据了绝大部分的业务操作,掌握这些基础注解的使用是很必要的.例如下面这段代码无需XML即可完成数据查询: @Mapper public interface UserMa

  • 详解Hibernate cascade级联属性的CascadeType的用法

    详解Hibernate cascade级联属性的CascadeType的用法 cascade(级联) 级联在编写触发器时经常用到,触发器的作用是当 主控表信息改变时,用来保证其关联表中数据同步更新.若对触发器来修改或删除关联表相记录,必须要删除对应的关联表信息,否则,会存有脏数据.所以,适当的做法是,删除主表的同时,关联表的信息也要同时删除,在hibernate中,只需设置cascade属性值即可. cascade表示级联操作,在hibernate配置注解@OneToOne,@OneToMany

  • 详解hibernate自动创建表的配置

    详解hibernate自动创建表的配置 配置自动创建表: <prop key="hibernate.hbm2ddl.auto">update</prop>//首次创建项目时用,项目稳定后一般注释这里有4个值: update:表示自动根据model对象来更新表结构,启动hibernate时会自动检查数据库,如果缺少表,则自动建表:如果表里缺少列,则自动添加列. 还有其他的参数: create:启动hibernate时,自动删除原来的表,新建所有的表,所以每次启动后

  • 详解 hibernate mapping配置

    详解 hibernate mapping配置 每个hibernate只会启动的时候引入一个文件,那就是:hibernate.cfg.xml mapping需要我们在hibernate中引入, <mapping resource="com/hibernate/test/hibernate_IP.xml"/> <mapping class="com.hibernate.test.Student"/> 代码片段: <?xml version=

  • 详解Hibernate注解方式的二级缓存

    详解Hibernate注解方式的二级缓存 hibernate默认情况下是支持一级缓存,也就是session级的缓存的,而默认情况下是不支持二级缓存,即sessionFactory级的缓存的,二级缓存        一般比较少去考虑它,除非对效率要求非常高的时候, 这时侯如果我们的某一个实体要在多个session里面使用需要用到session间的缓存的时候就可以进行配置来实现二级缓存了! 在看文档的时候说可以在persistence.xml里面进行配置,但我一般是不用这个文件的,就直接使用注解!

  • MyBatis多对多关联映射创建示例

    目录 示例 [通过班级查询老师信息] 示例 [通过班级查询老师信息] 创建t_classes 创建t_classessTeacher 创建t_teacher 创建Classes package com.po; import java.util.List; public class Classes { private Integer cid; private String cname; private List<Teacher> teachers; public Integer getCid()

  • Hibernate双向多对多映射关系配置代码实例

    1.实体类 package com.yl.bean; import java.io.Serializable; import java.util.Set; /** * 商品实体类 */ public class Goods implements Serializable { private Integer id;//商品id private String goodsName;//商品名 private Double price;//商品价格 private String remark;//备注

  • 详解用python实现基本的学生管理系统(文件存储版)(python3)

    这个是升级的版本,比较进阶一点的,相对与之前的文件管理系统,数据只是存储到了内存中,而不是存储到硬盘上,我们想让文件存储到硬盘上的话,一个是存储到文件里,一个是存储到数据库中,存储到数据库中的版本会后续发布,先来看一下文件存储版,是把学生信息存储到了txt文件中,我这里是默认存储到了students.txt文件中,想更改文件名字根据代码修改即可,代码中注释很详细,我也是python初学者,欢迎大家和我交流! """ 学生管理系统(文件存储版) 再原有功能的基础上添加了如下功能

  • 详解手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版)

    SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级架构方案.标准的MVC设计模式,将整个系统划分为显示层.Controller层.Service层.Dao层四层,使用SpringMVC负责请求的转发和视图管理,Spring实现业务对象管理, MyBatis作为数据对象持久化引擎. 一. 框架详情 Spring是一个轻量级的Java开发框架,它是为了解决企业应用开发的复杂性而创建的.Spring的用途不仅限于服务器端的开发.从简单性.可测试性和松耦合的角度而言,任何J

随机推荐