hibernate关联映射之一对多&多对一

package loaderman.b_one2Many;

import java.util.HashSet;
import java.util.Set;

public class Dept {

    private int deptId;
    private String deptName;
    // 【一对多】 部门对应的多个员工
    private Set<Employee> emps = new HashSet<Employee>();

    public int getDeptId() {
        return deptId;
    }
    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    public Set<Employee> getEmps() {
        return emps;
    }
    public void setEmps(Set<Employee> emps) {
        this.emps = emps;
    }




}
package loaderman.b_one2Many;

public class Employee {

    private int empId;
    private String empName;
    private double salary;
    // 【多对一】员工与部门
    private Dept dept;


    public int getEmpId() {
        return empId;
    }
    public void setEmpId(int empId) {
        this.empId = empId;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }


}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App1_save {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    // 保存, 部门方 【一的一方法操作】
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("应用开发部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);

        // 保存
        session.save(emp_zs);
        session.save(emp_ls);
        session.save(dept); // 保存部门,部门下所有的员工

        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  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=?    维护员工引用的部门的id
            Hibernate: update t_employee set deptId=? where empId=?
         */
    }
    // 【推荐】 保存, 部员方 【多的一方法操作】
    @Test
    public void save2() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("综合部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        emp_zs.setDept(dept);
        emp_ls.setDept(dept);


        // 保存
        session.save(dept); // 先保存一的方法
        session.save(emp_zs);
        session.save(emp_ls);// 再保存多的一方,关系会自动维护(映射配置完)

        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  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 (?, ?, ?)
            少生成2条update  sql
         */
    }

}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;


public class App2_get {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    @Test
    public void get() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 通过部门方,获取另外一方
//        Dept dept = (Dept) session.get(Dept.class, 1);
//        System.out.println(dept.getDeptName());
//        System.out.println(dept.getEmps());// 懒加载


        // 通过员工房,获取另外一方
        Employee emp = (Employee) session.get(Employee.class, 1);
        System.out.println(emp.getEmpName());
        System.out.println(emp.getDept().getDeptName());


        session.getTransaction().commit();
        session.close();
    }

}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;


public class App3_inverse {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    // 1. 保存数据
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("应用开发部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);  // inverse=true,  不会设置关联。
        //                 此时的关联应该通过员工方维护。


        // 保存
        session.save(emp_zs);
        session.save(emp_ls);
        session.save(dept); // 保存部门,部门下所有的员工

        session.getTransaction().commit();
        session.close();
    }

    //2. 是否设置inverse,对获取数据的影响?   无.
    @Test
    public void get() {
        Session session = sf.openSession();
        session.beginTransaction();

        Dept dept = (Dept) session.get(Dept.class, 1);
        System.out.println(dept.getDeptName());
        System.out.println(dept.getEmps());

        session.getTransaction().commit();
        session.close();
    }

    // 3. 是否设置inverse,对解除关联关系影响?
    // inverse=false,  可以解除关联
    // inverse=true,  当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
    //
    @Test
    public void removeRelation() {
        Session session = sf.openSession();
        session.beginTransaction();

        // 获取部门
        Dept dept = (Dept) session.get(Dept.class, 2);
        // 解除关系
        dept.getEmps().clear();

        session.getTransaction().commit();
        session.close();
    }


    //3. 是否设置inverse属性,在删除数据中对关联关系的影响?
    // inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
    // inverse=true,  没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束!
    //                             如果删除的记录没有被引用,可以直接删除。
    @Test
    public void deleteData() {
        Session session = sf.openSession();
        session.beginTransaction();

        // 查询部门
        Dept dept = (Dept) session.get(Dept.class, 8);
        session.delete(dept);


        session.getTransaction().commit();
        session.close();
    }









    @Test
    public void bak() {
        Session session = sf.openSession();
        session.beginTransaction();

        session.getTransaction().commit();
        session.close();
    }


}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;


public class App4_cascade {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    // 级联保存
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("财务部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);

        // 保存
//        session.save(emp_zs);
//        session.save(emp_ls);
        session.save(dept); // 需要设置级联保存; 保存部门,部门下所有的员工

        session.getTransaction().commit();
        session.close();
    }

    // 级联删除
    @Test
    public void delete() {
        Session session = sf.openSession();
        session.beginTransaction();

        Dept dept = (Dept) session.get(Dept.class,7);
        session.delete(dept); // 级联删除

        session.getTransaction().commit();
        session.close();
    }


    @Test
    public void bak() {
        Session session = sf.openSession();
        session.beginTransaction();

        session.getTransaction().commit();
        session.close();
    }


}
<?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="loaderman.b_one2Many">
    
    <class name="Dept" table="t_dept">
        <id name="deptId">
            <generator class="native"></generator>
        </id>    
        <property name="deptName" length="20"></property>
        
        <!-- 
            一对多关联映射配置  (通过部门管理到员工)
            Dept 映射关键点:
            1.  指定 映射的集合属性: "emps"
            2.  集合属性对应的集合表: "t_employee"
            3.  集合表的外键字段   "t_employee. dept_id"
            4.  集合元素的类型
            
            inverse=false  set集合映射的默认值; 表示有控制权
         -->
         <set name="emps" cascade="save-update,delete" table="t_employee" inverse="true">   <!-- table="t_employee" -->
              <key column="dept_id"></key>
              <one-to-many class="Employee"/>
         </set>
         
         
    </class>
    

</hibernate-mapping>
<?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="loaderman.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>
        
        <!-- 
            多对一映射配置
            Employee 映射关键点:
            1.  映射的部门属性  :  dept
            2.  映射的部门属性,对应的外键字段: dept_id
            3.  部门的类型
         -->
         <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
         
    </class>
    

</hibernate-mapping>
原文地址:https://www.cnblogs.com/loaderman/p/10037442.html