zoukankan      html  css  js  c++  java
  • 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 <!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     <class name="com.zlt.hibernatedemo.Grade" table="grade">
     7         <id name="id" column="id">
     8             <generator class="increment"></generator>
     9         </id>
    10         
    11         <property name="name" column="name"></property>
    12     </class>
    13 
    14 </hibernate-mapping> 

    学生类的定义以及hbm文件配置如下 

    1 public class Student {
    2     private int id;
    3     private String name;
    4     private Grade grade;
    5 }
     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     <class name="com.zlt.hibernatedemo.Student" table="student">
     7         <id name="id" column="id">
     8             <generator class="increment"></generator>
     9         </id>
    10         
    11         <property name="name" type="java.lang.String">  
    12             <column name="name" length="50" />  
    13         </property>
    14         
    15         <many-to-one name="grade" column="gradeid"></many-to-one>
    16     </class>
    17 
    18 </hibernate-mapping>

    测试程序

     1 public class HibernateTest {
     2     public static void main(String[] args) {
     3         Session session = HibernateFactory.currentSession();
     4         Transaction tx = session.beginTransaction();
     5         
     6         Grade grade = new Grade();
     7         grade.setName("grade1");
     8         
     9         Student student1 = new Student();
    10         student1.setName("student1");
    11         student1.setGrade(grade);
    12         
    13         Student student2 = new Student();
    14         student2.setName("student2");
    15         student2.setGrade(grade);
    16         
    17         session.save(grade);
    18         session.save(student1);
    19         session.save(student2);
    20         
    21         tx.commit();
    22         session.close();
    23     }
    24 }

    结果

    单向一对多

    多的一方:学生(Student)

    一的一方:班级(Grade)

    学生类的定义以及hbm文件配置如下 

    1 public class Student {
    2     private int id;
    3     private String name;    
    4 }
     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     <class name="com.zlt.hibernatedemo.Student" table="student">
     7         <id name="id" column="id">
     8             <generator class="increment"></generator>
     9         </id>
    10         
    11         <property name="name"></property>
    12     </class>
    13 
    14 </hibernate-mapping>

    班级类的定义以及hbm文件配置如下 

    1 public class Grade {
    2     private int id;
    3     private String name;
    4     private Set<Student> students = new HashSet<Student>(); 
    5 }
     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     <class name="com.zlt.hibernatedemo.Grade" table="grade">
     7         <id name="id" column="id">
     8             <generator class="increment"></generator>
     9         </id>
    10         
    11         <property name="name" column="name"></property>
    12         <set name="students">
    13             <key column="grade_id"/>
    14             <one-to-many class="com.zlt.hibernatedemo.Student"/>
    15         </set>
    16     </class>
    17 
    18 </hibernate-mapping>

    测试程序

     1 public class HibernateTest {
     2     public static void main(String[] args) {
     3         Session session = HibernateFactory.currentSession();
     4         Transaction tx = session.beginTransaction();
     5         
     6         Grade grade = new Grade();
     7         grade.setName("grade1");
     8         
     9         Student student1 = new Student();
    10         student1.setName("student1");
    11         
    12         Student student2 = new Student();
    13         student2.setName("student2");
    14         
    15         grade.getStudents().add(student1);
    16         grade.getStudents().add(student2);
    17         
    18         session.save(grade);
    19         session.save(student1);
    20         session.save(student2);
    21         
    22         tx.commit();
    23         session.close();
    24     }
    25

    结果

     

    <set>标签中可以设置cascade属性(all,save-update,delete,none)

    当不设置cascade时,保存时需要执行三条语句

    1 session.save(grade);
    2 session.save(student1);
    3 session.save(student2);

    当设置cascade="all"后对某个grade的操作会级联到它student,所以只需执行session.save(grade)就可以同时插入三条数据到数据库

    不设置cascade时,执行session.delete(grade);会把grade从数据库中删去,同时把student关联到这个grade的外键gradeid的值置为空;而设置了cascade后,删除了grade同时会把该grade对应的student对象从数据库中删去

    <set>标签中也可以设置inverse属性(true,false)

    inverse="false"(默认)生成的sql语句

    Hibernate: insert into grade (name, id) values (?, ?)

    Hibernate: insert into student (name, id) values (?, ?)

    Hibernate: insert into student (name, id) values (?, ?)

    Hibernate: update student set grade_id=? where id=?

    Hibernate: update student set grade_id=? where id=?

    inverse="true"生成的sql语句

    Hibernate: insert into grade (name, id) values (?, ?)

    Hibernate: insert into student (name, id) values (?, ?)

    Hibernate: insert into student (name, id) values (?, ?)

    同时数据库并没有关联三条数据

    它意味着 grade不再作为主控方,而将关联关系的维护工作交给关联对象student来完成。在保存grade时,grade不在关心student的gradeid属性,必须由student自己去维护,即设置student.setGrade(grade); 如果需要通过student来维护关联关系,那么这个关联关系转换成双向关联。

    双向关联

    学生

    1 public class Student {
    2     private int id;
    3     private String name;
    4     private Grade grade;
    5 }
     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     <class name="com.zlt.hibernatedemo.Student" table="student">
     7         <id name="id" column="id">
     8             <generator class="increment"></generator>
     9         </id>
    10         
    11         <property name="name" type="java.lang.String">  
    12             <column name="name" length="50" />  
    13         </property>
    14         
    15         <many-to-one name="grade" column="gradeid"></many-to-one>
    16     </class>
    17 
    18 </hibernate-mapping> 

    班级

    1 public class Grade {
    2     private int id;
    3     private String name;
    4     private Set<Student> students = new HashSet<Student>(); 
    5 }
     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     <class name="com.zlt.hibernatedemo.Grade" table="grade">
     7         <id name="id" column="id">
     8             <generator class="increment"></generator>
     9         </id>
    10         
    11         <property name="name" column="name"></property>
    12         
    13         <set name="students" inverse="true" cascade="all">
    14             <key column="gradeid"/>
    15             <one-to-many class="com.zlt.hibernatedemo.Student"/>
    16         </set>
    17     </class>
    18 
    19 </hibernate-mapping>

    测试程序

    public class HibernateTest {
        public static void main(String[] args) {
            Session session = HibernateFactory.currentSession();
            Transaction tx = session.beginTransaction();
            
            Grade grade = new Grade();
            grade.setName("grade1");
            
            Student student1 = new Student();
            student1.setName("student1");
            
            Student student2 = new Student();
            student2.setName("student2");
            
            //只需要session.save(grade);就能插入三条数据,需要先设置cascade
            grade.getStudents().add(student1);
            grade.getStudents().add(student2);
            
            //因为grade中inverse设置为ture,所以需要由student维护关联关系,设置graidid
            student1.setGrade(grade);
            student2.setGrade(grade);
            
            session.save(grade);
            tx.commit();
            session.close();
            
        }
    }

    结果:

    产生3条sql语句(如果用一的那端维护关联关系,会产生5条sql,所以在多的一方设置inverse="true",有助于性能的改善)

    Hibernate: insert into grade (name, id) values (?, ?)

    Hibernate: insert into student (name, gradeid, id) values (?, ?, ?)

    Hibernate: insert into student (name, gradeid, id) values (?, ?, ?)

    自身一对多配置

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     3     
     4     <hibernate-mapping>
     5         <class name="Category" table="category">
     6             <id name="id" type="string">
     7                 <column name="id"></column>
     8                 <generator class="uuid"></generator>
     9             </id>
    10             
    11             <property name="name" column="name" type="string"></property>
    12             
    13             <set name="chidrenCategories" cascade="all" inverse="true">
    14                 <key column="category_id"></key>
    15                 <one-to-many class=" Category"/>
    16             </set>
    17             
    18             <many-to-one name="parentCategory"  column="category_id"></many-to-one>
    19             
    20         </class>
    21     </hibernate-mapping>
  • 相关阅读:
    [Node.js] CommonJS Modules
    [Node.js] npm init && npm install
    [AngularJS] Hijacking Existing HTML Attributes with Angular Directives
    [Node.js] Level 7. Persisting Data
    [Express] Level 5: Route file
    [Express] Level 5: Route Instance -- refactor the code
    [Express] Level 4: Body-parser -- Delete
    [Express] Level 4: Body-parser -- Post
    [Express] Level 3: Massaging User Data
    [Express] Level 3: Reading from the URL
  • 原文地址:https://www.cnblogs.com/zanglitao/p/3817374.html
Copyright © 2011-2022 走看看