hibernate 2 多对多映射

Posted Mr·Liu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate 2 多对多映射相关的知识,希望对你有一定的参考价值。

一、实体类

1、Classes.java

 1 package cn.gs.wwg.entity;
 2 
 3 import java.util.Set;
 4 
 5 public class Classes {
 6     private int cid;
 7     private String cname;
 8     private String cdescription;
 9     private Set<Student> students;
10     public int getCid() {
11         return cid;
12     }
13     public void setCid(int cid) {
14         this.cid = cid;
15     }
16     public String getCname() {
17         return cname;
18     }
19     public void setCname(String cname) {
20         this.cname = cname;
21     }
22     public String getCdescription() {
23         return cdescription;
24     }
25     public void setCdescription(String cdescription) {
26         this.cdescription = cdescription;
27     }
28     public Set<Student> getStudents() {
29         return students;
30     }
31     public void setStudents(Set<Student> students) {
32         this.students = students;
33     }
34     
35 }

2、Student.java

 1 package cn.gs.wwg.entity;
 2 
 3 import java.io.Serializable;
 4 import java.util.Set;
 5 
 6 public class Student implements Serializable{
 7     private int sid;
 8     private String sname;
 9     private String sdescription;
10     private Set<Classes> classes;
11     
12 
13     public Set<Classes> getClasses() {
14         return classes;
15     }
16     public void setClasses(Set<Classes> classes) {
17         this.classes = classes;
18     }
19     public int getSid() {
20         return sid;
21     }
22     public void setSid(int sid) {
23         this.sid = sid;
24     }
25     public String getSname() {
26         return sname;
27     }
28     public void setSname(String sname) {
29         this.sname = sname;
30     }
31     public String getSdescription() {
32         return sdescription;
33     }
34     public void setSdescription(String sdescription) {
35         this.sdescription = sdescription;
36     }
37     
38 }

二:配置映射信息,建立表与类之间关系

1、Classes.hbm.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <!-- 
 7         class 用来描述一个持久化类
 8         name:持久化类全名
 9         table: 表名 可以不写 默认和实体类名一致
10      -->
11     <class name="cn.gs.wwg.entity.Classes" >
12         <!-- 
13             标示属性 和数据库中主键对应
14          -->
15         <id name="cid" column="cid" type="java.lang.Integer">
16             <!-- 主键产生器 -->
17             <generator class="assigned">
18 
19             </generator>
20         </id>
21         <property name="cname" column="cname" type="java.lang.String"></property>
22         <property name="cdescription" column="cdescription" type="java.lang.String"></property>
23         <!-- 
24             cascade="save-update"
25             当保存班级的时候对学生进行什么样的操作
26          -->
27         <set name="students" table="student_classes" cascade="all">
28             <!-- key用来描述外键
29                 set元素对应了classes类中的集合
30                 通过key是通过外键的形式将两张表建立联系
31                 通过one-to-many让两个类建立关联
32              -->
33             <key>
34                 <column name="cid"></column>
35             </key>
36             <many-to-many class="cn.gs.wwg.entity.Student" column="sid"></many-to-many>
37         </set>
38     </class>
39 </hibernate-mapping>

2、Student.hbm.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <!-- 
 7         class 用来描述一个持久化类
 8         name:持久化类全名
 9         table: 表名 可以不写 默认和实体类名一致
10      -->
11     <class name="cn.gs.wwg.entity.Student" >
12         <!-- 
13             标示属性 和数据库中主键对应
14          -->
15         <id name="sid" column="sid" type="java.lang.Integer">
16             <!-- 主键产生器 -->
17             <generator class="assigned">
18 
19             </generator>
20         </id>
21         <property name="sname" column="sname" type="java.lang.String"></property>
22         <property name="sdescription" column="sdescription" type="java.lang.String"></property>
23            <!-- 
24                多对一 column 描述外键
25             -->
26            <set name="classes" table="student_classes" cascade="all">
27             <!-- key用来描述外键
28                 set元素对应了classes类中的集合
29                 通过key是通过外键的形式将两张表建立联系
30                 通过one-to-many让两个类建立关联
31              -->
32             <key>
33                 <column name="sid"></column>
34             </key>
35             <many-to-many class="cn.gs.wwg.entity.Classes" column="cid"></many-to-many>
36         </set>
37     </class>
38 </hibernate-mapping>

三、编写配置文件,连接数据库,引入映射信息文件

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     
 6 <hibernate-configuration>
 7     <!-- 一个session-factory只能链接一个数据库  -->
 8     <session-factory>
 9         <!-- 
10         进行数据库连接
11             driver:驱动
12             url:地址
13             username:数据库连接用户名
14             password:数据库连接密码
15             数据库方言
16                   不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
17               sql99标准: DDL 定义语言  库表的增删改查
18                       DCL 控制语言  事务 权限
19                       DML 操纵语言  增删改查
20              注意: mysql在选择方言时,请选择最短的方言.            
21          -->
22          <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
23          <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
24          <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
25          <property name="connection.username">liuyang</property>
26          <property name="connection.password">orcl</property>
27          <!-- 
28              自动建表  
29                auto schema export  自动导出表结构. 自动建表
30                hibernate.hbm2ddl.auto create      自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
31                hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
32                hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
33                hibernate.hbm2ddl.auto validate    校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
34          -->
35 <!--          <property name="hbm2ddl.auto">update</property> -->
36          <property name="hbm2ddl.auto">update</property>
37          
38          <!-- 将hibernate生成的sql语句打印到控制台 -->
39          <property name="show_sql">true</property>    
40          <!-- 添加映射文件 -->        
41 <!--          <mapping resource="cn/gs/ly/entity/Person.hbm.xml"></mapping>      -->
42 <!--          <mapping resource="cn/gs/ly/school/entity/Student.hbm.xml"></mapping>          -->
43 <!--          <mapping resource="cn/gs/ly/school/entity/Classes.hbm.xml"></mapping>     -->
44          <mapping resource="cn/gs/wwg/entity/Classes.hbm.xml"></mapping>    
45          <mapping resource="cn/gs/wwg/entity/Student.hbm.xml"></mapping> 
46     </session-factory>
47 </hibernate-configuration>

 

四、测试类

ManyToManyTest.java

  1 package cn.gs.wwg.entity.test;
  2 
  3 import java.util.HashSet;
  4 import java.util.List;
  5 import java.util.Set;
  6 
  7 import org.hibernate.Session;
  8 import org.hibernate.SessionFactory;
  9 import org.hibernate.Transaction;
 10 import org.hibernate.cfg.Configuration;
 11 import org.junit.After;
 12 import org.junit.Before;
 13 import org.junit.Test;
 14 
 15 import cn.gs.wwg.entity.Classes;
 16 import cn.gs.wwg.entity.Student;
 17 
 18 public class ManyToManyTest {
 19     
 20     SessionFactory factory =null;
 21     Session se = null;
 22     Transaction tr = null;
 23     
 24     @Before
 25     public void beforeStart(){
 26         Configuration con = new Configuration();
 27         con.configure();
 28         factory = con.buildSessionFactory();
 29         se = factory.openSession();
 30         tr = se.beginTransaction();
 31     }
 32     @After
 33     public void afterClose(){
 34         tr.commit();
 35         se.close();
 36     }
 37     
 38     //3.新建一个班级的同时新建一个学生
 39     @Test
 40     public void testSaveStudent_Cascade_classes_Save(){
 41         
 42         Student student = new Student();
 43         student.setSid(1);
 44         student.setSname("小明");
 45         student.setSdescription("调皮捣蛋");
 46         
 47         Classes classes = new Classes();
 48         classes.setCid(1);
 49         classes.setCname("gs01");
 50         classes.setCdescription("有上升空间");
 51         
 52 //        Set<Classes> cla = new HashSet<Classes>();
 53 //        cla.add(classes);
 54 //        student.setClasses(cla);
 55         Set<Student> stu = new HashSet<Student>();//实例化一个Set集合存放学生
 56         stu.add(student); //把学生添加到集合中
 57         classes.setStudents(stu);
 58         se.save(classes);
 59 
 60     }
 61     
 62     // 4.已经存在一个班级,新建一个学生 建立联系  inverse (班级)
 63     @Test
 64     public void testUpdateclasses_Cascade_Student_Save_R(){
 65         Classes classes = (Classes)se.get(Classes.class, 1);
 66         Student student = new Student();
 67         student.setSid(2);
 68         student.setSname("萌萌");
 69         student.setSdescription("萌男人");        
 70         classes.getStudents().add(student);
 71         //se.save(student); 
 72 
 73     }
 74     
 75     // 4.已经存在一个班级,新建一个学生 建立联系  inverse (学生)
 76     @Test
 77     public void testSaveStudent_R(){
 78         Classes classes = (Classes)se.get(Classes.class, 1);
 79         Student student = new Student();
 80         student.setSid(3);
 81         student.setSname("神秘人");
 82         student.setSdescription("未知");
 83         Set<Classes> cla = new HashSet<Classes>();
 84         cla.add(classes);
 85         student.setClasses(cla);
 86         se.save(student);
 87 
 88     }
 89     
 90     //5.已经存在一个学生,新建一个班级 
 91     @Test
 92     public void testSaveStudent_CreateClass(){
 93         Student student = (Student)se.get(Student.class, 4);
 94         Classes classes = new Classes();
 95         classes.setCid(2);
 96         classes.setCname("gs02");
 97         classes.setCdescription("一群学霸");
 98         student.getClasses().add(classes);
 99     }
100     
101     //6.把一个学生从一个班级转到另一个班级。
102     @Test
103     public void testTransform(){        
104         Student student = (Student) se.get(Student.class, 1);//学生1从1班转到2班
105         Classes classes1 = (Classes)se.get(Classes.class, 1);
106         Classes classes2 = (Classes)se.get(Classes.class, 2);
107         student.getClasses().remove(classes1);
108         student.getClasses().add(classes2);
109     }
110     
111     //8.解除一个班级和一些学生的关系
112     @Test
113     public void test_Some(){
114         Student student = (Student)se.get(Student.class, 1);
115         Student student2 = (Student)se.get(Student.class, 2);
116         student.setClasses(null);
117         student2.setClasses(null);
118     }
119     
120     //11.已经存在了一个班级,也存在许多学生 建立班级与学生的关系。方法一
121     @Test
122     public void testR_Some(){
123         Classes classes = (Classes)se.get(Classes.class,1);
124         Student student = (Student)se.get(Student.class, 1);
125         Student student2 = (Student)se.get(Student.class, 2);
126         student.getClasses().add(classes);
127         student2.getClasses().add(classes);
128 //        classes.getStudents().add(student2);Ч???
129 //        classes.getStudents().add(student);
130     }
131     
132     //11.已经存在了一个班级,也存在许多学生 建立班级与学生的关系。方法二
133     @Test
134     public void testR_Some_2(){
135         Classes classes = (Classes)se.get(Classes.class,1);
136         List<Student> studentList = se.createQuery("from Student where sid in(1,2)").list();
137         classes.getStudents().addAll(studentList);
138     }
139     
140     //12.已经存在了一些班级,也存在许多学生 建立班级与学生的关系。(每名学生都有多个班级)
141     @Test
142     public void testR_Some_3(){
143         List<Student> studentList = se.createQuery("from Student where sid in(3,4)").list();
144         List<Classes> classesList = se.createQuery("from Classes where cid in(1,2)").list();
145         for(Student s:studentList){
146             s.getClasses().addAll(classesList); //学生3、4都关联两个班级1、2
147         }        
148     }
149     
150     //13.删除班级
151     @Test
152     public void testR_Some_5(){
153         Classes classes = (Classes)se.get(Classes.class, 2);
154         //classes.setStudents(null);  //解除关系   inverse="true"时需此操作
155         se.delete(classes);    
156     }
157 }

 

以上是关于hibernate 2 多对多映射的主要内容,如果未能解决你的问题,请参考以下文章

hibernate 2 多对多映射

Hibernate学习笔记 --- 创建基于中间关联表的多对多映射关系

Hibernate课程 初探多对多映射2-4 测试

Hibernate学习8—Hibernate 映射关系(多对多)

Hibernate多对多关系映射(建表)

Hibernate hbm 多对多映射