java Hibernate多对多映射详解及实例代码

java Hibernate多对多映射

前言:

一、单向多对多

单向多对多的例子用人和职位来举例,一个人可以有多个职位,一个职位会有多个人。单向多对多是指只能在一端来查询获取另一端的内容。多对多的关系在生成关系模型时会生成对象之前的关联表,关联表中存放着两个关系表的主键,它们的关系如下所示:

代码部分: 

(1)映射和关系类

因为是单向的关系,所以只需要在一端进行维护,所以我们需要在User.hbm.xml配置文件中添加<many-to-many>标签,并在标签中加上对应的列关系,在<set>表中添加table属性来指明生成新表,User.hbm.xml代码如下:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><hibernate-mapping>
  <class name="com.bjpowernode.hibernate.User" table="t_user">
    <id name="id">
      <generator class="native"/>
    </id>
    <property name="name"/>
    <set name="roles" table="t_user_role">
      <key column="user_id"/>
      <many-to-many class="com.bjpowernode.hibernate.Role" column="role_id" />
    </set>
  </class>
</hibernate-mapping></span> 

Role.hbm.xml代码比较简单,不需要添加多余的标签来维护关系:

<hibernate-mapping>
  <class name="com.bjpowernode.hibernate.Role" table="t_role">
    <id name="id">
      <generator class="native"/>
    </id>
    <property name="name"/>
  </class>
</hibernate-mapping> 

因为user的映射中有set映射,所以需要在相应的类文件中添加Hashset,User.java代码如下:

<span style="font-family:KaiTi_GB2312;font-size:18px;">import java.util.Set; 

public class User { 

  private int id; 

  private String name; 

  private Set roles; 

  public int getId() {
    return id;
  } 

  public void setId(int id) {
    this.id = id;
  } 

  public String getName() {
    return name;
  } 

  public void setName(String name) {
    this.name = name;
  } 

  public Set getRoles() {
    return roles;
  } 

  public void setRoles(Set roles) {
    this.roles = roles;
  }
}</span> 

Role.java代码如下:

public class Role { 

  private int id; 

  private String name; 

  public int getId() {
    return id;
  } 

  public void setId(int id) {
    this.id = id;
  } 

  public String getName() {
    return name;
  } 

  public void setName(String name) {
    this.name = name;
  }
} 

(2)添加和读取数据:

进行添加数据时,需要首先吧关系保存到数据库中,然后创建用户Hash表,在hash表中添加对应的关系,最后创建用户,将hash表添加到用户上。这部分需注意的是写入的先后顺序,否则会出现很多null值,和之前的映射一样的道理。

public void testSave1() {
    Session session = null;
    try {
      session = HibernateUtils.getSession();
      session.beginTransaction(); 

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

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

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

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

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

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

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

读取时因为是单向关系,只需要通过一来读取另一端的内容,通过user来读取role的内容。代码如下:

public void testLoad1() {
    Session session = null;
    try {
      session = HibernateUtils.getSession();
      session.beginTransaction();
      User user = (User)session.load(User.class, 2);
      System.out.println(user.getName());
      for (Iterator iter=user.getRoles().iterator(); iter.hasNext();) {
        Role role = (Role)iter.next();
        System.out.println(role.getName());
      }
      session.getTransaction().commit();
    }catch(Exception e) {
      e.printStackTrace();
      session.getTransaction().rollback();
    }finally {
      HibernateUtils.closeSession(session);
    }
  }   

二、双向多对多映射

和之前介绍的一样,双向多对多就是在两端同时维护关系,从任何一端都能加载到另一端的内容,话不多说直接上代码:

因为是双向的所以需要同时加入双向的集合映射,在配置文件中添加<set>标签,添加多对多标签,Role.hbm.xml代码如下:

<hibernate-mapping>
  <class name="com.bjpowernode.hibernate.Role" table="t_role">
    <id name="id">
      <generator class="native"/>
    </id>
    <property name="name"/>
    <set name="users" table="t_user_role">
      <key column="role_id" not-null="true"/>
      <many-to-many class="com.bjpowernode.hibernate.User" column="user_id"/>
    </set>
  </class>
</hibernate-mapping> 

User.hbm.xml代码如下,和单向映射代码是一样的:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><hibernate-mapping>
  <class name="com.bjpowernode.hibernate.Role" table="t_role">
    <id name="id">
      <generator class="native"/>
    </id>
    <property name="name"/>
    <set name="users" table="t_user_role">
      <key column="role_id" not-null="true"/>
      <many-to-many class="com.bjpowernode.hibernate.User" column="user_id"/>
    </set>
  </class>
</hibernate-mapping>
</span> 

Role.java部分,和单向的user.java一样需要添加集合映射set,代码如下:

import java.util.Set; 

public class Role { 

  private int id; 

  private String name; 

  private Set users; 

  public int getId() {
    return id;
  } 

  public void setId(int id) {
    this.id = id;
  } 

  public String getName() {
    return name;
  } 

  public void setName(String name) {
    this.name = name;
  } 

  public Set getUsers() {
    return users;
  } 

  public void setUsers(Set users) {
    this.users = users;
  }
} 

User.hbm.xml和User.java代码和上文中的代码相同,就不全部放上来了。

小结:

单向和多向通过几篇博客的介绍相信大家已经明白,我们只需要记住单向的双向的也就会了,挺简单的。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Java Hibernate对象(瞬时态,持久态,脱管态)详解

    Java Hibernate对象            由于最近学习Java Hibernate,这里对Java Hibernate对象的几种状态进行了资料整理,  有兴趣的朋友可以看下. 瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象. 持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交: 持久对象状态发生改变,在事务提交时

  • Java的Hibernate框架中的组合映射学习教程

    一.组合映射 组合是关联关系的一种特殊情况,是关联关系耦合度最高的一种关系,组合的主对象和子对象拥有相同的生命周期,主对像消亡的话子对象也会消亡.这里使用雇主和用户作为示例,用户和雇主都拥有联系方式属性,如果这里站在对象角度思考的话,常常会把对象模型绘制成为组合的方式,抽象出来一个共同的联系方式类,然后两种人分别包含相应的联系方式对象即可,向应的对象模型时它的对象示例如下图所示: 组合对象模型在生成相应的关系模型后会把对应的子类包含到主表中,所以对应的表结构会将相应的属性生成到对应的表中,相应的

  • Java的Hibernate框架结合MySQL的入门学习教程

    零.关于Hibernate Hibernate是冬眠的意思,它是指动物的冬眠,但是本文讨论的Hibernate却与冬眠毫无关系,而是接下来要讨论的SSH2框架中的一员.Hibernate是一个开源的项目,它是一个对象关系模型的框架,并且对JDBC进行了非常轻量级的封装,程序员在开发时可以使用对象编程思维进行开发. 下载地址:http://hibernate.org/orm/downloads/ Note:轻量级和重量级的区别,轻量级的框架包较小,并且使用较简单,而且测试容易,开发效率高:重量级框

  • java hibernate使用注解来定义联合主键

    java  hibernate使用注解来定义联合主键 下面使用hibernate的API中说明的三种方式来定义主键,主要使用Annotation来定义hibernate中的联合主键 下面取至hibernate的API文档: 定义组合主键的几种语法: 1.将组件类注解为@Embeddable,并将组件的属性注解为@Id 2.将组件的属性注解为@EmbeddedId 3.将类注解为@IdClass,并将该实体中所有属于主键的属性都注解为@Id 下面就分别使用这三种方式来定义联合主键. 建表的SQL语

  • Java的Hibernate框架中复合主键映射的创建和使用教程

    复合主键映射需要在映射配置文件中使用<composite-id>标签,该标签是指将一个类指定为相应的复合主键,它的name属性需要指定类文件中定义的属性值,并在该标签中添加<key-property>子标签. Note:想要使用复合映射必须要将复合主键放到一个类中,也就是讲复合主键属性和其它属性分到两个类中,并将复合主键的类实现接口Serializable,该接口隶属于java.io. 复合主键的映射关系的主键是由多个列复合而成的,对应到数据表中相当的简单,如下图: 1.类文件 这

  • Java探索之Hibernate主键生成策略详细介绍

    1.increment 由Hibernate从数据库中去除主键的最大值(每个session只取一次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库. <id name="id" column="id"> <generator class="increment" /> </id> Hibernate调用org.hibernate.id.IncrementGenerator类

  • java Hibernate多对多映射详解及实例代码

    java Hibernate多对多映射 前言: 一.单向多对多 单向多对多的例子用人和职位来举例,一个人可以有多个职位,一个职位会有多个人.单向多对多是指只能在一端来查询获取另一端的内容.多对多的关系在生成关系模型时会生成对象之前的关联表,关联表中存放着两个关系表的主键,它们的关系如下所示: 代码部分:  (1)映射和关系类 因为是单向的关系,所以只需要在一端进行维护,所以我们需要在User.hbm.xml配置文件中添加<many-to-many>标签,并在标签中加上对应的列关系,在<s

  • java 实现单链表逆转详解及实例代码

    java 实现单链表逆转详解 实例代码: class Node { Node next; String name; public Node(String name) { this.name = name; } /** * 打印结点 */ public void show() { Node temp = this; do { System.out.print(temp + "->"); temp = temp.next; }while(temp != null); System.o

  • Java 装箱与拆箱详解及实例代码

    Java 装箱与拆箱详解 前言: 要理解装箱和拆箱的概念,就要理解Java数据类型 装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质.int包装成Integer.float包装成Float 拆箱:和装箱相反,将引用类型的对象简化成值类型的数据 Integer a = 100; 这是自动装箱 (编译器调用的是static Integer valueOf(int i)) int b = new Integer(100); 这是自动拆箱 看下面一段代码 m1 public class

  • Java 使用json-lib处理JSON详解及实例代码

    Java 使用json-lib处理JSON详解 [项目环境] <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> 1. JSON 数组对象转化

  • Java中的Static class详解及实例代码

     Java中的Static class详解 Java中的类可以是static吗?答案是可以.在Java中我们可以有静态实例变量.静态方法.静态块.类也可以是静态的. java允许我们在一个类里面定义静态类.比如内部类(nested class).把nested class封闭起来的类叫外部类.在java中,我们不能用static修饰顶级类(top level class).只有内部类可以为static. 静态内部类和非静态内部类之间到底有什么不同呢?下面是两者间主要的不同. (1)内部静态类不需

  • java LRU(Least Recently Used )详解及实例代码

    java LRU(Least Recently Used )详解 LRU是Least Recently Used 的缩写,翻译过来就是"最近最少使用",LRU缓存就是使用这种原理实现,简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉,比如我们缓存10000条数据,当数据小于10000时可以随意添加,当超过10000时就需要把新的数据添加进来,同时要把过期数据删除,以确保我们最大缓存10000条,那怎么确定删除哪条过期数据呢,采用LRU算法实现的话就是将最老的数据

  • C++/java 继承类的多态详解及实例代码

    C++/java 继承类的多态详解 学过C++和Java的人都知道,他们二者由于都可以进行面向对象编程,而面向对象编程的三大特性就是封装.继承.多态,所有今天我们就来简单了解一下C++和Java在多态这方面的不同. 首先我们各看一个案例. C++ //测试继承与多态 class Animal { public: char name[128]; char behavior[128]; void outPut() { cout << "Animal" << endl

  • Java大文件上传详解及实例代码

    Java大文件上传详解 前言: 上周遇到这样一个问题,客户上传高清视频(1G以上)的时候上传失败. 一开始以为是session过期或者文件大小受系统限制,导致的错误.查看了系统的配置文件没有看到文件大小限制,web.xml中seesiontimeout是30,我把它改成了120.但还是不行,有时候10分钟就崩了. 同事说,可能是客户这里服务器网络波动导致网络连接断开,我觉得有点道理.但是我在本地测试的时候发觉上传也失败,网络原因排除. 看了日志,错误为: java.lang.OutOfMemor

  • Java中的代理模式详解及实例代码

    java 代理模式详解 前言: 在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为"代理"的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外服务. 简单来说代理模式就是通过一个代理对象去访问一个实际对象,并且可以像装饰模式一样给对象添加一些功能. 静态代理 所谓静态代理即在程序运行前代理类就已经存在,也就是说我们编写代码的时候就已经把代理类的代码写好了,而动态代理则

  • java 反射和动态代理详解及实例代码

    一.java中的反射 1.通过反射加载类的属性和方法实例代码: /** * java.lang.Class 是反射的源头 * 我们创建了一个类,通过编译(javac.exe)生成对应的class文件,之后我们通过java.exe加载(jvm的类加载器加载)此class文件 * 此class文件加载到内存后,就是一个运行时类,存在缓存区,这个运行时类本事就是一个Class的实例 * 每一个运行时类只加载一次, */ Class<StudentExam> clazz = StudentExam.c

随机推荐