• 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 }
  • 相关阅读:
    SpringBoot-整合多数据源
    SpringBoot-整合@transactional注解
    SpringBoot-整合mybatis
    SpringBoot-区分不同环境配置文件
    SpringBoot-@value自定义参数
    SpringBoot-@async异步执行方法
    bias与variance,欠拟合与过拟合关系
    从贝叶斯到深度学习各个算法
    基础机器学习算法
    推荐算法总结
  • 原文地址:https://www.cnblogs.com/liuyangv/p/8405944.html
Copyright © 2020-2023  润新知