hibernate Framework-Association Mapping (hibernate Mapping)

Keywords: Hibernate Session xml Database

Set Mapping

  • Development process: requirements analysis/database design, project design/coding/testing/implementation deployment online/acceptance
  • Requirements: User purchase, fill in the address!
  • Database Design: Not available yet
  • Code

    • javabean design
      public class User {
            private int userId;
            private String userName;
            // One user, corresponding to multiple addresses
            private Set<String> address;
            private List<String> addressList = new ArrayList<String>(); 
            //private String[] addressArray; //Map as list, <array name="></array>
            private Map<String,String> addressMap = new HashMap<String, String>();    
      }
    • Mapping file hib.xml

      <?xml version="1.0"?>
      <!DOCTYPE hibernate-mapping PUBLIC 
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
      "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
      <hibernate-mapping package="cn.itcast.a_collection">
      <class name="User" table="t_user">
          <id name="userId" column="id">
              <generator class="native"></generator>
          </id>    
          <property name="userName"></property>
      
          <!-- 
              set Mapping of Collection Properties
                  name Specify which to map set Properties of a collection
                  table Table to which collection attributes are mapped
                  key  Specify Collection Table(t_address)Foreign Key Fields
                  element Specify additional fields for the collection table
                      type Element type, must specify
           -->
           <set name="address" table="t_address">
               <key column="uid"></key>
               <element column="address" type="string"></element>
           </set>
      
           <!-- 
               list Set Mapping
                   list-index  The name of the sorted column is specified (Because you want to make sure list Order of sets)
            -->
            <list name="addressList" table="t_addressList">
                  <key column="uid"></key>
                  <list-index column="idx"></list-index>
                  <element column="address" type="string"></element>
            </list>
      
            <!-- 
                map Mapping of sets
                    key  Specify Foreign Key Fields
                    map-key Appoint map Of key 
                    element  Appoint map Of value
             -->
            <map name="addressMap" table="t_addressMap">
                <key column="uid"></key>
                <map-key column="shortName" type="string" ></map-key>
                <element column="address" type="string" ></element>
            </map>
      </class>
      </hibernate-mapping>
    • java class

      // Save set
      @Test
      public void testSaveSet() throws Exception {
          Session session = sf.openSession();
          session.beginTransaction();
      
          //--Save
          Set<String> addressSet = new HashSet<String>();
          addressSet.add("Guangzhou");
          addressSet.add("Shenzhen");
      
          // User Objects
          User user = new User();
          user.setUserName("Jack");
          user.setAddress(addressSet);
      
          // Preservation
          session.save(user);
      
          session.getTransaction().commit();
          session.close();
      }
      // Save list/map
      @Test
      public void testSaveList() throws Exception {
          Session session = sf.openSession();
          session.beginTransaction();
          User user = new User();
          user.setUserName("Tom");
      //        //User Object--list
      //        user.getAddressList().add("Guangzhou");
      //        user.getAddressList().add("Shenzhen");
      //        //Save
      //        session.save(user);
      
          // User Object -- Map
          user.getAddressMap().put("A0001", "Guangzhou");
          user.getAddressMap().put("A0002", "Shenzhen");
      
          // Preservation
          session.save(user);
      
          session.getTransaction().commit();
          session.close();
      }
  • Question: Collection mapping, mapped collection elements are common types, can they be object types?

Association Mapping

  • Many-to-one mapping and one-to-many

    • Requirements: Employees and Departments
    • Database:
    • Design javabean encapsulation:
      public class Dept {
              private int deptId;
              private String deptName;
              // Multiple employees in the Department
              private Set<Employee> emps = new HashSet<Employee>();
      }    
      public class Employee {
              private int empId;
              private String empName;
              private double salary;
              // Employees and Departments
              private Dept dept;
      }
    • Mapping:

      • Dept.hbm.xml :

        <?xml version="1.0"?>
        <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        <hibernate-mapping package="cn.itcast.b_one2Many">
        <class name="Dept" table="t_dept">
          <id name="deptId">
              <generator class="native"></generator>
          </id>    
          <property name="deptName" length="20"></property>
        
          <!-- 
              One-to-many association mapping configuration (managed by department to employees)
              Dept Mapping Key Points:
              1. Specify the set property of the map:'emps'
              2. The set table corresponding to the set property:'t_employee'
              3. The foreign key field "t_employee. dept_id" of the set table
              4. Types of collection elements
        
           -->
           <set name="emps">   <!-- table="t_employee" -->
                <key column="dept_id"></key>
                <one-to-many class="Employee"/>
           </set>
        </class>
        </hibernate-mapping>
      • Employee.hbm.xml :

        <?xml version="1.0"?>
        <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        <hibernate-mapping package="cn.itcast.b_one2Many">
        <class name="Employee" table="t_employee">
          <id name="empId">
              <generator class="native"></generator>
          </id>    
          <property name="empName" length="20"></property>
          <property name="salary" type="double"></property>
        
          <!-- 
              Many-to-one mapping configuration
              Employee mapping key points:
              1. Departmental attributes of mapping: dept
              2. Departmental property of the map, corresponding foreign key field: dept_id
              3. Type of Department
           -->
           <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
        </class>
        </hibernate-mapping>
    • Test:

      public class App {
      private static SessionFactory sf;
      static {
          sf = new Configuration()
              .configure()
              .addClass(Dept.class)   
              .addClass(Employee.class)   // Use during testing
              .buildSessionFactory();
      }
      // Save, Department [a method operation of one]
      @Test
      public void save() {
          Session session = sf.openSession();
          session.beginTransaction();
      
          // Department Objects
          Dept dept = new Dept();
          dept.setDeptName("Application Development Department");
          // Employee Objects
          Employee emp_zs = new Employee();
          emp_zs.setEmpName("Zhang San");
          Employee emp_ls = new Employee();
          emp_ls.setEmpName("Li Si");
          // relationship
          dept.getEmps().add(emp_zs);
          dept.getEmps().add(emp_ls);
      
          // Preservation
          session.save(emp_zs);
          session.save(emp_ls);
          session.save(dept); // Save department, all employees under Department  
      
          session.getTransaction().commit();
          session.close();
          /*
           *  Result
           *  Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
              Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
              Hibernate: insert into t_dept (deptName) values (?)
              Hibernate: update t_employee set deptId=? where empId=?    Maintain the id of the Department referenced by the employee
              Hibernate: update t_employee set deptId=? where empId=?
           */
      }
      // [Recommendation] Save, Ministry [more than one method of operation]
      @Test
      public void save2() {
      
          Session session = sf.openSession();
          session.beginTransaction();
      
          // Department Objects
          Dept dept = new Dept();
          dept.setDeptName("General Department");
          // Employee Objects
          Employee emp_zs = new Employee();
          emp_zs.setEmpName("Zhang San");
          Employee emp_ls = new Employee();
          emp_ls.setEmpName("Li Si");
          // relationship
          emp_zs.setDept(dept);
          emp_ls.setDept(dept);    
      
          // Preservation
          session.save(dept); // First Save One Method
          session.save(emp_zs);
          session.save(emp_ls);// Save more parties, relationship back to automatic maintenance (mapping configured)
          session.getTransaction().commit();
          session.close();
          /*
           *  Result
           *  Hibernate: insert into t_dept (deptName) values (?)
              Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
              Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
              Less than 2 update SQLs
           */
      }    
      }
    • Summary: In a one-to-many and many-to-one relationship, the best way to preserve data is to maintain the relationship through many parties, which can reduce the generation of update statements and improve the execution efficiency of hibernate!

      Configuring one-to-many and many-to-one is called bidirectional association
      Configure only one-to-many, called "one-to-many single"
      Configure many-to-one only, called "single many-to-one"
      Note: Which party is configured has the right to maintain the relationship!

  • Many-to-many mapping

    • Requirements: Projects and Developers
    • data base
    • Code

      • Entity class:
        // Developer
        public class Developer {
           private int d_id;
           private String d_name;
           // Developer, multiple projects for parameters
           private Set<Project> projects = new HashSet<Project>();
        }
        // project
        public class Project {
           private int prj_id;
           private String prj_name;
           // Multiple employees under the project
           private Set<Developer> developers = new HashSet<Developer>();
        }
      • Mapping file:

        • Project.hbm.xml
          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping PUBLIC 
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
          <hibernate-mapping package="cn.itcast.c_many2many">
          <class name="Project" table="t_project">
          <id name="prj_id">
             <generator class="native"></generator>
          </id>    
          <property name="prj_name" length="20"></property>
          <!-- 
             Many-to-many mapping:
             1. Mapped collection property:'developers'
             2. Collection properties, corresponding intermediate table:'t_relation'
             3. Foreign key field: prjId
             4. Foreign key field, corresponding intermediate table field: did
             5. Types of Collection Attribute Elements
          -->
          <set name="developers" table="t_relation" cascade="save-update">
              <key column="prjId"></key>
              <many-to-many column="did" class="Developer"></many-to-many>
          </set>
          </class>
          </hibernate-mapping>
        • Developer.hbm.xml :

          <?xml version="1.0"?>
          <!DOCTYPE hibernate-mapping PUBLIC 
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
          <hibernate-mapping package="cn.itcast.c_many2many">
          <class name="Developer" table="t_developer">
          <id name="d_id">
             <generator class="native"></generator>
          </id>    
          <property name="d_name" length="20"></property>
          
          <!-- 
             Many-to-many mapping configuration: employee side
                 name Specifies the set property of the map
                 Intermediate table corresponding to table collection properties
                 Key specifies the foreign key field of the intermediate table (referencing the foreign key field of the current table t_developer primary key)
                 many-to-many
                     column specifies the project field corresponding to the foreign key field
                     Type of class collection element
          -->
          <set name="projects" table="t_relation">
             <key column="did"></key>
             <many-to-many column="prjId" class="Project"></many-to-many>
          </set>
          </class>
          </hibernate-mapping>
  • Inverse and cascade attributes

    • Inverse property
      • The Inverse property works when maintaining relationships.Indicates whether control is transferred (in effect on one side)
      • Inverse: Control Inversion
        • Inverse = false does not reverse; the current party has control
        • Inverse =True control reversal; current party has no control
    • cascade attribute
      • Cascade represents a cascade operation [one or more parties that can be set to]
      • none: no cascade, default
      • save-update: cascade save or update
      • Delete: cascade delete
      • save-update,delete: cascade save, update, delete
      • all: Same as above (cascade save, update, delete)
    • hibernate FAQ: The difference between inverse and cascade?
  • Maintain affiliation

    • Setting the inverse attribute has multiple effects on maintaining relationships?
      1) Saving data: impacting
      inverse=false: Control allows you to maintain the association; object relationships are inserted into the intermediate table when you save data
       inverse=true: No control, no data will be inserted into the intermediate table
      2) Access to data: no impact
      3) Disengagement: Impactful
      inverse=false: With control, dissolving the relationship means deleting the data from the intermediate table
       inverse=true: cannot dissolve without control
      4) Delete data: impacting
      inverse=false: Control - >Delete intermediate table data before deleting itself
       inverse=true: no control - > error if deleted data is referenced; delete if not referenced

Posted by TravisJRyan on Thu, 11 Jul 2019 09:32:51 -0700