hibernate 2 一对多、多对一 双向映射

多对一或一对多中,在多的一方维护关系效率高

一:java实体类

1、Classes.java

 1 package cn.gs.ly.school.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.ly.school.entity;
 2 
 3 public class Student {
 4     private int sid;
 5     private String sname;
 6     private String sdescription;
 7     private Classes classes;
 8     
 9     public int getSid() {
10         return sid;
11     }    
12     public void setSid(int sid) {
13         this.sid = sid;
14     }
15     public String getSname() {
16         return sname;
17     }
18     public void setSname(String sname) {
19         this.sname = sname;
20     }
21     public String getSdescription() {
22         return sdescription;
23     }
24     public void setSdescription(String sdescription) {
25         this.sdescription = sdescription;
26     }
27     public Classes getClasses() {
28         return classes;
29     }
30     public void setClasses(Classes classes) {
31         this.classes = classes;
32     }
33     
34 }

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

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    
 6 <!-- 配置表与实体对象的关系 --> 
 7 <hibernate-mapping>
 8     <class name="cn.gs.ly.school.entity.Classes"  >
 9         <id name="cid" column="cid" type="java.lang.Integer">
10             <generator class="assigned"></generator>
11         </id>
12         <property name="cname" column="cname" type="java.lang.String"></property>
13         <property name="cdescription" column="cdescription" type="java.lang.String"></property>    
14         
15         <!--         
16             cascade="save-update" 级联操作
17             当保存班级的时候对学生进行什么操作 
18             inverse="false" 是否维护关系
19                 true不维护关系、false维护关系
20         -->
21         <set name="students" cascade="save-update" inverse="false">  <!-- 级联 -->
22             <!-- 
23                 key 用来描述外键 
24                 set元素对用classes类中的set集合
25                 通过key是  通过外键的形式将两张表建立联系
26                 通过one-to-many让两个类建立关联
27             -->
28             <key>
29                 <column name="cid"></column>
30             </key>
31             <one-to-many class="cn.gs.ly.school.entity.Student"/>
32         </set>                    
33     </class>
34     
35 </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    
 6 <!-- 配置表与实体对象的关系 --> 
 7 <hibernate-mapping>
 8     <class name="cn.gs.ly.school.entity.Student"  >
 9         <id name="sid" column="sid" type="java.lang.Integer">
10             <generator class="assigned"></generator>
11         </id>
12         <property name="sname" column="sname" type="java.lang.String"></property>
13         <property name="sdescription" column="sdescription" type="java.lang.String"></property>    
14         <!-- 多对一column 描述外键 -->
15         <many-to-one name="classes" class="cn.gs.ly.school.entity.Classes" column="cid" cascade="save-update"></many-to-one>    
16     </class>
17     
18 </hibernate-mapping>

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

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     </session-factory>
45 </hibernate-configuration>

三:测试类

oneToManyTest.java

  1 package cn.gs.ly.school.test;
  2 
  3 import java.util.ArrayList;
  4 import java.util.HashSet;
  5 import java.util.List;
  6 import java.util.Set;
  7 
  8 import org.hibernate.SessionFactory;
  9 import org.hibernate.Transaction;
 10 import org.hibernate.cfg.Configuration;
 11 import org.hibernate.classic.Session;
 12 import org.junit.After;
 13 import org.junit.Before;
 14 import org.junit.Test;
 15 
 16 import cn.gs.ly.school.entity.Classes;
 17 import cn.gs.ly.school.entity.Student;
 18 import sun.util.calendar.CalendarSystem;
 19 
 20 /** Hibernate执行流程:
 21  *         Configuration:读取并解析配置文件(hibernate.cfg.xml)
 22  *             一个Configuration实例代表hibernate所有的java类到SQL数据库映射的集合
 23  *         SessionFactory:读取并解析映射信息(***.hbm.xml)
 24  *             将Configuration对象中的所有配置信息拷贝到SessionFactory的缓存中
 25  *         打开Session,让SessionFactory提供连接。
 26  *            SessionFactory factory = con.buildSessionFactory(); 
 27  *        Transaction:开启事务。
 28  *            Transaction tr = se.beginTransaction();
 29  *        数据库操作(get,delete,update,save)完成:提交事务、关闭Session
 30  *            tr.commit(); 
 31  *            se.close();
 32  *
 33  * Hibernate对象三种状态
 34  *         save():将对象由瞬时态转变为持久态
 35  *         liad()/get():获得的对象的状态处于持久态
 36  *         find():获得的List集合中的对象的状态处于持久态
 37  *         upload()/saveOrUpload()/lock():可将托管状态对象转变为持久态
 38  *         close():调用后,Session的缓存会被清空,缓存中所有持久态对象状态都转变为托管态
 39  *             处于托管状态的对象称为游离对象,当游离对象不再被引用时,将被JVM垃圾回收机制清除
 40  *         evict():可将Session缓存中一个指定的持久态对象删除,使其转变为托管态对象
 41  *             当缓存中保存了大量持久态对象时,为了节省内存空间,可以调用此方法删除一些持久态对象
 42  *         
 43  * */
 44 
 45 public class OneToManySingleTest {    
 46     SessionFactory factory =null;
 47     Session se = null;
 48     Transaction tr = null;
 49     
 50     //@Before:读取并解析配置文件、映射信息、打开Session、开启事务
 51     @Before
 52     public void test1(){                
 53         //读取配置文件   //1 创建,调用空参构造
 54         Configuration con = new Configuration();
 55         //2 读取指定主配置文件 => 空参加载方法,加载src下的hibernate.cfg.xml文件
 56         con.configure();
 57         //创建一个session工厂      //4 根据配置信息,创建 SessionFactory对象
 58         factory = con.buildSessionFactory();
 59         //5 获得session  打开一个新的session对象
 60         se = factory.openSession();
 61         //开启事务   //开启事务并获得操作事务的tr对象(建议使用)
 62         tr = se.beginTransaction();
 63     }
 64     //@After:提交事务、关闭Session
 65     @After
 66     public void afterClose(){
 67         //提交事务
 68         tr.commit();
 69         //关闭session
 70         se.close();
 71     }
 72 
 73     //1.新建一个班级
 74     @Test 
 75     public void testCreateClasses(){
 76         Classes classes = new Classes();
 77         classes.setCid(1);
 78         classes.setCname("gs01");
 79         classes.setCdescription("一群大老爷们");
 80         se.save(classes);
 81     }
 82     
 83     //2.新建一个学生
 84     @Test 
 85     public void testCreateStudent(){
 86         Student student = new Student();
 87         student.setSid(1);
 88         student.setSname("张涛");
 89         student.setSdescription("诸城一爷们");
 90         se.save(student);
 91     }
 92     
 93     //3.新建一个班级的同时新建一个学生
 94     @Test 
 95     public void testCreateStudentClasses(){
 96         Student student = new Student();
 97         student.setSid(2);
 98         student.setSname("刘超");
 99         student.setSdescription("中华小题库");        
100         
101         Classes classes = new Classes();
102         classes.setCid(2);
103         classes.setCname("gs02");
104         classes.setCdescription("一群学霸");
105         
106         Set<Student> stus = new HashSet<Student>();
107         stus.add(student);
108         classes.setStudents(stus);
109         se.save(classes);
110     }
111     
112     //4.已经存在一个班级,新建一个学生。建立联系:inverse(true不维护关系,false不维护关系)
113     @Test 
114     public void testUpdateClass_Inverse_createStudent(){
115         Classes classes = (Classes)se.get(Classes.class, 1); //id为1 的班级即gs01
116         
117         Student student = new Student();
118         student.setSid(3);
119         student.setSname("萌萌");
120         student.setSdescription("一个光头的男人");
121         
122         classes.getStudents().add(student);
123         //se.update(classes);
124     }
125     
126     //5.已经存在一个学生,新建一个班级
127     @Test  
128     public void testCreateClassLinkStudent(){        
129         Classes classes = new Classes();
130         classes.setCid(3);
131         classes.setCname("gs03");
132         classes.setCdescription("一个新的班级");
133         
134         Student student = (Student)se.get(Student.class, 1);
135         
136         Set<Student> stus = new HashSet<Student>();
137         stus.add(student);        
138         classes.setStudents(stus);
139         se.save(classes);
140     }
141     
142     //6.把一个学生从一个班级转到另一个班级
143     @Test 
144     public void testMoveStudent(){        
145         Student student = (Student)se.get(Student.class, 1); //获得要转班的学生
146         Classes classes = (Classes)se.get(Classes.class, 2); //获得要转到的那个班级
147         //Classes classes1 = (Classes)se.get(Classes.class, 3);//原来的班级
148         //classes1.getStudents().remove(student); //把这个学生从原来班级删除
149         classes.getStudents().add(student);  //把这个学生添加到要转去的那个新班级
150     }
151     
152     //7.解除一个班级和一个学生的关系
153     @Test 
154     public void test7(){        
155         Student student = (Student)se.get(Student.class, 4); //获得要转班的那个学生
156         Classes classes = (Classes)se.get(Classes.class, 3); //获得这个学生原来所在的班级
157         classes.getStudents().remove(student); //把这个学生从原来班级删除
158     }
159     
160     //8.解除一个班级和一些学生的关系
161     @Test 
162     public void test8(){        
163         Classes classes = (Classes)se.get(Classes.class, 3); //解除关系的班级
164         Set<Student> students = classes.getStudents(); //此班级里所有学生,返回set集合
165         //set无下标,只查看集合不修改集合,所以用list集合进行修改 ,Set转List
166         List<Student> list = new ArrayList<Student>(students);
167         for (int i=0;i<list.size();i++) {
168             if(list.get(i).getSid()==4||list.get(i).getSid()==6){ //id为4和6的学生
169                 list.remove(i);//移除后,集合大小动态改变,集合大小-1
170                 i--;           //集合变小,i也需要变化
171             }
172         }
173         //List转Set集合,
174         students = new HashSet<Student>(list);
175         classes.setStudents(students);
176     }
177     
178     //9.解除一个班级和所有学生的关系
179     @Test 
180     public void test9(){            
181         Classes classes = (Classes)se.get(Classes.class, 3); //获得一个班级
182 //        Set<Student> students = classes.getStudents();
183 //        students.clear();    
184         classes.setStudents(null);
185     }
186     
187     //10.已经存在了一个班级,也存在一个学生 建立班级与学生的关系
188     @Test 
189     public void test10(){        
190         Classes classes = (Classes)se.get(Classes.class, 2); // id 为1 的班级即gs01
191         Student student = (Student)se.get(Student.class, 7);        
192         classes.getStudents().add(student);
193     }
194     
195     @Test //11.已经存在了一个班级,也存在许多学生 建立班级与学生的关系
196     public void test11(){    //未完成    =====================    
197 //        Classes classes = (Classes)se.get(Classes.class, 3);
198 //        Set<Student> students = classes.getStudents();
199 //        //set无下标,只查看集合不修改集合,所以用list集合 ,set转list
200 //        List<Student> list = new ArrayList<Student>(students);
201 //        for (int i=0;i<list.size();i++) {
202 //            if(list.get(i).getSid()==4||list.get(i).getSid()==5||list.get(i).getSid()==6){
203 //                
204 //            }else{
205 //                list.remove(i);
206 //            }
207 //        }
208 //        //list转set集合
209 //        students = new HashSet<Student>(list);
210 //        classes.setStudents(students);
211     }
212     
213     //12.删除学生
214     @Test 
215     public void test12(){    
216         Student student = (Student)se.get(Student.class, 2);
217         se.delete(student);
218     }
219     
220      // 13.删除班级(需先解除关系)       
221      //     1.在删除班级前,解除班级与学生之间的关系: inverse="false" 维护关系 删除班级解除关系
222      //     2.在删除班级的时候同时删除学生: 级联操作  cascade="all" 或  cascade="delete"
223     @Test  
224     public void test13(){        
225         Classes classes = (Classes)se.get(Classes.class, 3);
226         //classes.setStudents(null);  //解除关系   inverse="true"时需此操作来解除关系
227         se.delete(classes);        
228     }
229         
230 }

ManyToOneTest.java

  1 package cn.gs.ly.school.test;
  2 
  3 import java.util.ArrayList;
  4 import java.util.HashSet;
  5 import java.util.List;
  6 import java.util.Set;
  7 
  8 import org.hibernate.SessionFactory;
  9 import org.hibernate.Transaction;
 10 import org.hibernate.cfg.Configuration;
 11 import org.hibernate.classic.Session;
 12 import org.junit.After;
 13 import org.junit.Before;
 14 import org.junit.Test;
 15 
 16 import cn.gs.ly.school.entity.Classes;
 17 import cn.gs.ly.school.entity.Student;
 18 import sun.util.calendar.CalendarSystem;
 19 
 20 public class ManyToOneSingleTest2 {
 21     
 22     SessionFactory factory =null;
 23     Session se = null;
 24     Transaction tr = null;
 25     @Before
 26     public void test1(){
 27         //读取配置文件   //1 创建,调用空参构造
 28         Configuration con = new Configuration();
 29         //2 读取指定主配置文件 => 空参加载方法,加载src下的hibernate.cfg.xml文件
 30         con.configure();
 31         //创建一个session工厂      //4 根据配置信息,创建 SessionFactory对象
 32         factory = con.buildSessionFactory();
 33         //5 获得session  打开一个新的session对象
 34         se = factory.openSession();
 35         //开启事务   //开启事务并获得操作事务的tr对象(建议使用)
 36         tr = se.beginTransaction();
 37     }
 38     @After
 39     public void afterClose(){
 40         //提交事务
 41         tr.commit();
 42         //关闭session
 43         se.close();
 44     }
 45 
 46 // 一对多双向
 47     /**
 48      *     多对一或一对多中,在多的一方维护关系效率高       student角度
 49      * 
 50      * */
 51     
 52     @Test //1.新建一个班级
 53     public void testCreateClasses(){
 54         Classes classes = new Classes();
 55         classes.setCid(10);
 56         classes.setCname("gs010");
 57         classes.setCdescription("一群大老爷们");
 58         se.save(classes);
 59     }
 60     
 61     @Test //2.新建一个学生
 62     public void testCreateStudent(){
 63         Student student = new Student();
 64         student.setSid(10);
 65         student.setSname("张涛");
 66         student.setSdescription("诸城一爷们");
 67         se.save(student);
 68     }
 69     
 70     @Test //3.新建一个班级的同时新建一个学生  
 71     public void testCreateStudentClasses(){
 72         Student student = new Student();
 73         student.setSid(11);
 74         student.setSname("刘杨");
 75         student.setSdescription("学霸");        
 76         
 77         Classes classes = new Classes();
 78         classes.setCid(21);
 79         classes.setCname("gs021");
 80         classes.setCdescription("一群学霸");
 81         
 82         student.setClasses(classes);
 83         se.save(student);
 84     
 85     }
 86     
 87     @Test //4.已经存在一个班级,新建一个学生                  建立联系  inverse(true不维护false维护)
 88     public void testUpdateClass_Inverse_createStudent(){
 89         Classes classes = (Classes)se.get(Classes.class, 21); // id 为1 的班级即gs01
 90         Student student = new Student();
 91         student.setSid(12);
 92         student.setSname("萌萌");
 93         student.setSdescription("一个光头的男人");
 94         
 95         student.setClasses(classes);
 96         se.save(student);
 97     }
 98     
 99 //    @Test //5.已经存在一个学生,新建一个班级 
100 //    public void testCreateClassLinkStudent(){        
101 //        Classes classes = new Classes();
102 //        classes.setCid(3);
103 //        classes.setCname("gs03");
104 //        classes.setCdescription("一个新的班级");
105 //        
106 //        Student student = (Student)se.get(Student.class, 1);
107 //        
108 //        Set<Student> stus = new HashSet<Student>();
109 //        stus.add(student);        
110 //        classes.setStudents(stus);
111 //        se.save(classes);
112 //    }
113 //    
114 //    @Test //6.把一个学生从一个班级转到另一个班级
115 //    public void testMoveStudent(){        
116 //        Student student = (Student)se.get(Student.class, 1); //获得要转班的那个学生
117 //        Classes classes = (Classes)se.get(Classes.class, 2); //获得要转到的那个班级
118 //        //Classes classes1 = (Classes)se.get(Classes.class, 3);//原来的班级
119 //        //classes1.getStudents().remove(student); //把这个学生从原来班级删除
120 //        classes.getStudents().add(student);  //把这个学生添加到要转去的那个新班级
121 //    }
122 //    
123 //    @Test //7.解除一个班级和一个学生的关系
124 //    public void test7(){        
125 //        Student student = (Student)se.get(Student.class, 4); //获得要转班的那个学生
126 //        Classes classes = (Classes)se.get(Classes.class, 3); //获得这个学生原来所在的班级
127 //        classes.getStudents().remove(student); //把这个学生从原来班级删除
128 //    }
129     
130     @Test //8.解除一个班级和一些学生的关系
131     public void test8(){        
132         //Classes classes = (Classes)se.get(Classes.class, 21);
133         Student s1 = (Student)se.get(Student.class, 4);
134         Student s2 = (Student)se.get(Student.class, 5);
135         s1.setClasses(null);
136         s2.setClasses(null);
137     }
138     
139     @Test //9.解除一个班级和所有学生的关系
140     public void test9(){            
141         Classes classes = (Classes)se.get(Classes.class, 3); 
142 //        Set<Student> students = classes.getStudents();
143 //        students.clear();    
144         classes.setStudents(null);
145     }
146     
147     @Test //10.已经存在了一个班级,也存在一个学生 建立班级与学生的关系
148     public void test10(){        
149         Classes classes = (Classes)se.get(Classes.class, 2); // id 为1 的班级即gs01
150         Student student = (Student)se.get(Student.class, 7);        
151         classes.getStudents().add(student);
152     }
153     
154     @Test //11.已经存在了一个班级,也存在许多学生 建立班级与学生的关系
155     public void test11(){        
156         Classes classes = (Classes)se.get(Classes.class, 3);
157         Set<Student> students = classes.getStudents();
158         //set无下标,只查看集合不修改集合,所以用list集合 ,set转list
159         List<Student> list = new ArrayList<Student>(students);
160         for (int i=0;i<list.size();i++) {
161             if(list.get(i).getSid()==4||list.get(i).getSid()==5||list.get(i).getSid()==6){
162                 
163             }else{
164                 list.remove(i);
165             }
166         }
167         //list转set集合
168         students = new HashSet<Student>(list);
169         classes.setStudents(students);
170     }
171     
172     @Test //12.删除学生
173     public void test12(){    
174         Student student = (Student)se.get(Student.class, 2);
175         se.delete(student);
176     }
177     
178     @Test // 13.删除班级    (解除关系)       
179           // 1.在删除班级前,解除班级与学生之间的关系: inverse="false" 维护关系 删除班级解除关系
180           // 2.在删除班级的时候同时删除学生: cascade="all" 或  cascade="delete"  
181     public void test13(){        
182         Classes classes = (Classes)se.get(Classes.class, 3);
183         //classes.setStudents(null);  //解除关系   inverse="true"时需此操作
184         se.delete(classes);        
185     }
186 
187 }
原文地址:https://www.cnblogs.com/liuyangv/p/8405944.html