Hibernate关系映射之many-to-many(多对多)

软件152 刘安民

在表设计中,我们一般都会考虑表与表之间的关系,现在我来介绍一下表与表之间的几种对应关系many-to-many 多对多 比如一个用户可以有多种角色 一种角色可以对用多个不同的用户所以角色和用户之间的关系是多对多的关系 一般要用第三张表表示两者对应的关系one-to-many 一对多  比如一个老师可以对应很多个学生many-to-one 相反的是多对一  one-to-one  一对一 比如公民和身份证就是一一对应的

Demo实验:学生与课程之间的关系

1.创建StuCourse类和StuCourse.hbm.xml 表示StudentCourse之间的对应关系
 1 package com.ansibee.domain;
 2
 3 public class StuCourse {
 4     private Integer id;
 5     private Student student;
 6     private Course course;
 7     private Integer grade;
 8     public Integer getId() {
 9         return id;
10     }
11     public void setId(Integer id) {
12         this.id = id;
13     }
14     public Student getStudent() {
15         return student;
16     }
17     public void setStudent(Student student) {
18         this.student = student;
19     }
20     public Course getCourse() {
21         return course;
22     }
23     public void setCourse(Course course) {
24         this.course = course;
25     }
26     public Integer getGrade() {
27         return grade;
28     }
29     public void setGrade(Integer grade) {
30         this.grade = grade;
31     }
32 }

<!--StuCourse.hbm.xml-->

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping package="com.ansibee.domain">
 5 <class name="StuCourse" >
 6 <id name="id" type="java.lang.Integer">
 7 <generator class="increment">
 8 <param name="increment">stucourse_inc</param>
 9 </generator>
10 </id>
11 <property name="grade" type="java.lang.Integer">
12 <column name="grade" length="3"/>
13 </property>
14 <many-to-one name="course" column="course_id"/>
15 <many-to-one name="student" column="student_id"/>
16 </class>
17 </hibernate-mapping>

2.创建Student类和Student.hbm.xml文件
 1 package com.ansibee.domain;
 2
 3 import java.util.Set;
 4
 5 public class Student {
 6     private Integer id;
 7     private String name;
 8     private Set<StuCourse> stuCourses;
 9     public Integer getId() {
10         return id;
11     }
12     public void setId(Integer id) {
13         this.id = id;
14     }
15     public String getName() {
16         return name;
17     }
18     public void setName(String name) {
19         this.name = name;
20     }
21     public Set<StuCourse> getStuCourses() {
22         return stuCourses;
23     }
24     public void setStuCourses(Set<StuCourse> stuCourses) {
25         this.stuCourses = stuCourses;
26     }
27 }

<!--Student.hbm.xml-->

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping package="com.ansibee.domain">
 5 <class name="Student">
 6 <id name="id" type="java.lang.Integer">
 7 <generator class="increment">
 8 <param name="increment">stu_inc</param>
 9 </generator>
10 </id>
11 <property name="name" type="java.lang.String">
12 <column name="name" length="64"/>
13 </property>
14 <!-- 这里我们配置了one-to-many 一个学生可以对应多个选课记录 -->
15 <set name="stuCourses">
16 <key column="student_id"/>
17 <one-to-many class="StuCourse"/>
18 </set>
19 </class>
20 </hibernate-mapping>

 3.创建Course类和Course.hbm.xml文件

 1 package com.ansibee.domain;
 2
 3 import java.util.Set;
 4
 5 public class Course {
 6     private Integer id;
 7     private String name;
 8     private Set<StuCourse> stuCourses;
 9     public Integer getId() {
10         return id;
11     }
12     public void setId(Integer id) {
13         this.id = id;
14     }
15     public String getName() {
16         return name;
17     }
18     public void setName(String name) {
19         this.name = name;
20     }
21     public Set<StuCourse> getStuCourses() {
22         return stuCourses;
23     }
24     public void setStuCourses(Set<StuCourse> stuCourses) {
25         this.stuCourses = stuCourses;
26     }
27 }

<!--Course.hbm.xml-->

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping package="com.ansibee.domain">
 5 <class name="Course">
 6 <id name="id" type="java.lang.Integer">
 7 <generator class="increment">
 8 <param name="increment">course_inc</param>
 9 </generator>
10 </id>
11 <property name="name" type="java.lang.String">
12 <column name="name" length="64"/>
13 </property>
14 <!-- 配置one-to-many 表示一门课程可以对应多个选课记录 -->
15 <set name="stuCourses">
16 <key column="course_id"/>
17 <one-to-many class="StuCourse"/>
18 </set>
19 </class>
20 </hibernate-mapping>

4.完成以上步骤就可以创建Hibernate工具类完成CRUD操作

  1 package com.ansibee.util;
  2 import java.util.List;
  3
  4 import org.hibernate.Query;
  5 import org.hibernate.Session;
  6 import org.hibernate.SessionFactory;
  7 import org.hibernate.Transaction;
  8 import org.hibernate.cfg.Configuration;
  9
 10 final public class HibernateUtil {
 11     private static SessionFactory sessionFactory=null;
 12     //使用线程局部模式
 13     private static ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();
 14     private HibernateUtil(){};
 15     static {
 16         sessionFactory=new Configuration().configure().buildSessionFactory();
 17     }
 18
 19     //关闭sessionFactory
 20     public static void closeSessionFactory(){
 21         sessionFactory.close();
 22     }
 23
 24     //获取全新的全新的session
 25     public static Session openSession(){
 26         return sessionFactory.openSession();
 27     }
 28     //获取和线程关联的session
 29     public static Session getCurrentSession(){
 30
 31         Session session=threadLocal.get();
 32         //判断是否得到
 33         if(session==null){
 34             session=sessionFactory.openSession();
 35             //把session对象设置到 threadLocal,相当于该session已经和线程绑定
 36             threadLocal.set(session);
 37         }
 38         return session;
 39
 40     }
 41
 42     //提供一个统一的查询方法 hql形式 from类 where 条件=?..
 43     public static List executeQuery(String hql,String[] parameters){
 44
 45         Session session = null;
 46         List list = null;
 47
 48         try {
 49             session = openSession();
 50             Query query = session.createQuery(hql);
 51             //先判断是否有参数绑定
 52             if(parameters!=null&&parameters.length>0){
 53                 for(int i=0;i<parameters.length;i++){
 54                     query.setString(i, parameters[i]);
 55                 }
 56             }
 57             list = query.list();
 58         } catch (Exception e) {
 59             e.printStackTrace();
 60             throw new RuntimeException(e.getMessage());
 61         }finally{
 62             if(session!=null&&session.isOpen()){
 63                 session.close();
 64             }
 65         }
 66         return list;
 67     }
 68
 69     //提供一个统一的查询方法(带分页)hql形式 from 类  where 条件=?..
 70     public static List executeQueryByPage(String hql,String[] parameters,int pageSize,int pageNow){
 71
 72         Session session = null;
 73         List list = null;
 74
 75         try {
 76             session = openSession();
 77             Query query = session.createQuery(hql);
 78             //先判断是否有参数绑定
 79             if(parameters!=null&&parameters.length>0){
 80                 for(int i=0;i<parameters.length;i++){
 81                     query.setString(i, parameters[i]);
 82                 }
 83             }
 84
 85             //分页
 86             query.setFirstResult((pageNow-1)*pageSize).setMaxResults(pageSize);
 87
 88             list = query.list();
 89         } catch (Exception e) {
 90             e.printStackTrace();
 91             throw new RuntimeException(e.getMessage());
 92         }finally{
 93             if(session!=null&&session.isOpen()){
 94                 session.close();
 95             }
 96         }
 97         return list;
 98     }
 99
100     //统一的添加方法
101     public static void save(Object obj){
102         Session session=null;
103         Transaction ts=null;
104
105         try {
106             session=openSession();
107             ts=session.beginTransaction();
108             session.save(obj);
109             ts.commit();
110         } catch (Exception e) {
111             if(ts!=null){
112                 ts.rollback();
113             }
114             throw new RuntimeException(e.getMessage());
115         }finally{
116             if(session!=null&&session.isOpen()){
117                 session.close();
118             }
119         }
120     }
121
122     //统一提供一个修改和删除(批量hql)hql"delete update ...??"
123     public static void executeUpdate(String hql,String[] parameters){
124
125         Session session=null;
126         Transaction ts =null;
127         try {
128             session=openSession();
129             ts=session.beginTransaction();
130             Query query=session.createQuery(hql);
131             //先判断是否有参数要绑定
132             if(parameters!=null&&parameters.length>0){
133                 for(int i=0;i<parameters.length;i++){
134                     query.setString(i, parameters[i]);
135                 }
136             }
137             query.executeUpdate();
138             ts.commit();
139         } catch (Exception e) {
140             e.printStackTrace();
141             throw new RuntimeException(e.getMessage());
142         }finally{
143             if(session!=null&&session.isOpen()){
144                 session.close();
145             }
146         }
147     }
148 }

5.配置hibernate.cfg.xml

 1 <?xml version=‘1.0‘ encoding=‘UTF-8‘?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3           "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4           "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <!-- Generated by MyEclipse Hibernate Tools.                   -->
 6 <hibernate-configuration>
 7
 8     <session-factory>
 9         <property name="myeclipse.connection.profile">com.mysql.jdbc.Driver</property>
10         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
11         <property name="connection.password">123</property>
12         <property name="connection.username">root</property>
13         <property name="connection.url">jdbc:mysql://localhost:3306/employee</property>
14         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
15         <property name="show_sql">true</property>
16         <!-- 配置让hibernate自动创建关系模型(表) -->
17         <property name="format_sql">false</property>
18         <property name="hbm2ddl.auto">update</property>
19         <mapping resource="com/ansibee/domain/Course.hbm.xml" />
20         <mapping resource="com/ansibee/domain/StuCourse.hbm.xml" />
21     <mapping resource="com/ansibee/domain/Student.hbm.xml" />
22     </session-factory>
23
24 </hibernate-configuration>

6.编写测试类TestMain

 1 package com.ansibee.view;
 2
 3 import org.hibernate.Session;
 4 import org.hibernate.Transaction;
 5
 6 import com.ansibee.domain.Course;
 7 import com.ansibee.domain.StuCourse;
 8 import com.ansibee.domain.Student;
 9 import com.ansibee.util.HibernateUtil;
10
11 public class TestMain {
12
13     public static void main(String[] args) {
14
15         Session session = null;
16         Transaction ts = null;
17
18         try {
19             // 使用基础模板
20             session = HibernateUtil.getCurrentSession();
21             ts = session.beginTransaction();
22
23             //添加一个学生,一门课程,选课
24             Student stu1 = new Student();
25             stu1.setName("小共");
26
27             Course course = new Course();
28             course.setName("C#");
29
30             StuCourse sc = new StuCourse();
31             sc.setGrade(95);
32             sc.setCourse(course);
33             sc.setStudent(stu1);
34
35             //顺序保存
36             session.save(stu1);
37             session.save(course);
38             session.save(sc);
39
40             ts.commit();
41         } catch (Exception e) {
42             if (ts != null) {
43                 ts.rollback();
44             }
45             e.printStackTrace();
46
47             // TODO: handle exception
48         } finally {
49             if (session != null && session.isOpen()) {
50                 session.close();
51             }
52         }
53     }
54
55 }

7.测试运行

时间: 2024-08-29 03:32:15

Hibernate关系映射之many-to-many(多对多)的相关文章

hibernate关系映射(多对多)

多对多关系(学生Student,课程Course) 学生类的定义以及hbm文件的配置如下 1 public class Student { 2 private int id; 3 private String name; 4 private Set<Course> courses = new HashSet<Course>(); 5 } 1 <?xml version="1.0" encoding="UTF-8"?> 2 <

hibernate关系映射(多对一)

对多一关系是最普遍也是最重要的一种对象关系,其中又包括了单向的多对一,单向的一对多以及双向的多对一关系 单向多对一 多的一方:学生(Student) 一的一方:班级(Grade) 班级类的定义以及hbm文件配置如下 1 public class Grade { 2 private int id; 3 private String name; 4 } 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTY

Java学习笔记-Hibernate关系映射

1. 初识Hibernate——关系映射 http://blog.csdn.net/laner0515/article/details/12905711 2. Hibernate 笔记8 关系映射1(多对一,一对多): http://www.cnblogs.com/zilong882008/archive/2011/11/05/2236559.html 3. Hibernate关联映射 http://www.cnblogs.com/huxi/archive/2009/12/15/1624988.

hibernate 关系映射文件配置

<!--Department.hbm.xml users属性,本类与User的一对多 --> <set name="users"> <key column="departmentId"></key> <one-to-many class="User" /> </set> <!-- parent属性,本类与Department(上级)的多对一 --> <man

浅谈Hibernate关系映射(3)

继上篇博客 一对多关联映射(单向) 上面我们介绍了多对一,我们反过来看一对多不就是多对一吗?那还用再进行不同的映射吗?有什么差别吗?一对多和多对一映射原理是一致的,存储是相同的,也就是生成的数据库的表是一样的,他们之间不同的是维护的关系不同. 他们之间不同点是维护的关系不同 *多对一维护的关系是:多指向一的关系,有了此关系,加载多的时候可以将一加载上来. *一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来. 一个班级有多个学生,通过班级可以看到学生信息. Class

浅谈Hibernate关系映射(2)

继上篇博客 一对一关系映射:一对一关联映射在实际生活中是比较常见的,如人与身份证的关系,通过人这个对象可以找到他相关的内容. 一对一单向(主键): 单向一对一主键关联,靠的是它们的主键相等,从Person中能看到IdCard,也就是把t_idCard中的主键拿过来当做t_Pseron的主键. 如图的线表示一个关联,在person中可以看见idcard.即在person中持有idCard的引用 person类的映射关系 <hibernate-mapping> <class name=&qu

浅谈Hibernate关系映射(4)

继上篇博客 多对多关联映射(单向) 多对多对象关系映射,需要加入一张新表完成基本映射. Hibernate会自动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联,多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的. 如下图所示 通过User可以查看Role的信息 User的映射文件 <hibernate-mapping> <class name="com.bjpowernode.hibernate.User"> <

hibernate关系映射(一对一)

一对一关联分为外键关联和主键关联:外键关联是指从表中存在主表的外键,这也是一种特殊的多对一关系:主键关联是指主从表的id一致 外键关联 主表:IDCard(校园卡) 从表:Student(学生) 学生类的定义和hbm文件的配置如下 1 public class Student { 2 private int id; 3 private String name; 4 //持有idcard的外键 5 private IDCard idCard; 6 }  可以看到 学生持有校园卡外键的类结构和之前多

Hibernate关系映射基础

1.  Hibernate关系映射基础 1.1.  Doctype <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 指定根元素和dtd文件的命名空间. 1.2.  hibernate-mapping <hiberna

Hibernate关系映射(三) 多对一和一对多

一.多对一 学生Student和班级Grade实现多对一,多个学生对应一个班级. Student.java实体类,映射了班级的属性. package com.lxit.entity; import java.io.Serializable; public class Student implements Serializable {          public Student() {     } public Student(String sname, String sex, String