映射:一对多(部门对员工)和多对一(员工对部门)

package dao.po;
import java.util.Set;
//部门类
public class Department{
    private int id;//部门的ID
    private String name;//部门的名称
    private Set<Employee> emps;//部门下的所有员工 (一对多关系)  
}
package dao.po;
//员工类
public class Employee{
    private int id;// 员工的ID
    private String name;// 员工的名称
    private Department depart;//员工所在部门 (是多对一关系)  
}  

  XML:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="dao.po">
    <class name="Department">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name" not-null="true" length="255" column="name"/>
        <set name="emps">     <!-- emps 是Department的一个属性 -->
            <key column="depart_id"></key>  <!-- 通过员工表的 depart_id字段来关联,它是字段名 -->
            <one-to-many class="Employee"/>   <!-- emps的类型是Employee -->
        </set>
    </class>
</hibernate-mapping>  

下面是重点:

   <set name="emps">        <!-- emps 是Department的一个属性 -->    
            <key column="depart_id"></key>    <!-- 通过员工表的 depart_id字段来关联,它是字段名 -->
            <one-to-many class="Employee"/>    <!-- emps的类型是Employee -->
        </set>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="dao.po">
    <class name="Employee">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name" not-null="true" length="255" column="`name`"/>
        <!-- 这里做多对一映射    -->
        <!-- name="depart"是Employee类的属性名 -->
        <!-- column="depart_id" 是表中字段名 -->  
        <many-to-one name="depart" column="depart_id" not-null="true"></many-to-one>
    </class>
</hibernate-mapping>  

一对多 (一个部门 对 多个员工):查询部门(部门下有员工)

public static void main(final String[] args){
    final Department de = query(2);
    final Set<Employee> set = de.getEmps(); //本部门的所有员工
    for (final Employee em : set){
        System.out.println(em.getName());
    }
}
/**
 * 查询部门(部门下有员工)
 * @param id  部门ID
 * @return 部门对象
 */
public static Department query(final int id){
    Session session = null;
    try{
        session = HibernateUtil.getSeesion();
        final Transaction tx = session.beginTransaction();
        final Department de = (Department) session.get(Department.class, id); //按ID查
        //因为 部门的 "员工" 属性会懒加载,
        //在session关闭后,调用de.getEmps()无法取到员工信息
        //所以这里用 Hibernate.initialize(de.getEmps()) 提前加载一下.
        Hibernate.initialize(de.getEmps());
        tx.commit();
        return de;
    }finally{
        if (session != null){
            session.close();
        }
    }
}

二、多对一(员工对部门)

package dao.po;
// 员工类
public class Employee  {
    private int id; // 员工的ID
    private String name; // 员工的名称
    private Department depart;    //员工所在部门, 是多对一关系
}  
package dao.po;
//部门类
public class Department  {
    private int id; //部门的ID
    private String name;   //部门的名称
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping  package="dao.po">
    <class name="Employee">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name" not-null="true" length="255" column="`name`"/>
        <!-- 这里做多对一映射    -->
        <!-- name="depart"是Employee类的属性名 -->
        <!-- column="depart_id" 是表中字段名 -->
        <!-- 注意:下面没有非空 约束 , 很多情况,外键是有非空约束的, 一会后面说-->
        <!--column="depart_id" 中的depart_id是Employee对象的depart属性映射为Employee表中的depart_id字段-->
        <many-to-one name="depart" column="depart_id" ></many-to-one>
    </class>
</hibernate-mapping>  
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping  package="dao.po">
    <class name="Department">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name" not-null="true" length="255" column="`name`"/>
</class>
</hibernate-mapping>  

  保存员工 和 部门:

package dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import dao.po.Department;
import dao.po.Employee;
//多对一的例子 , 多个员工 对 一个部门
public class Many2One{
    public static void main(final String[] args){
        add(); //添加两个员工, 一个部门
    }
    //添加两个员工, 一个部门
    public static void add(){
        final Department depart = new Department(); //部门
        depart.setName("技术部");
        final Employee em1 = new Employee(); //员工 一
        em1.setName("赵磊");
        em1.setDepart(depart);
        final Employee em2 = new Employee(); //员工 二
        em2.setName("陈加俊");
        em2.setDepart(depart);
        Session session = null;
        try{
            session = HibernateUtil.getSeesion();
            final Transaction tx = session.beginTransaction();
            session.save(depart); //先插入部门
            session.save(em1); //后插入员工, 因为员工的外键是 部门
            session.save(em2);
            tx.commit();
        }finally{
            if (session != null){
                session.close();
            }
        }
    }
}  

  注意:保存的顺序:

  第一种:

session.save(depart); //先插入部门
            session.save(em1); //后插入员工, 因为员工的外键是 部门
            session.save(em2);

  输出的SQL:

Hibernate: insert into Department (`name`) values (?)
            Hibernate: insert into Employee (`name`, depart_id) values (?, ?)
            Hibernate: insert into Employee (`name`, depart_id) values (?, ?)

  第二种:

session.save(em1); //先插入员工
            session.save(em2);
            session.save(depart); //后插入部门

  输出的SQL:

Hibernate: insert into Employee (`name`, depart_id) values (?, ?)
            Hibernate: insert into Employee (`name`, depart_id) values (?, ?)
            Hibernate: insert into Department (`name`) values (?)
            Hibernate: update Employee set `name`=?, depart_id=? where id=?
            Hibernate: update Employee set `name`=?, depart_id=? where id=?

  这里多了两句 update,要 注意:如果Employee.hbm.xml 中外键有非空约束,如下:保存时只能用" 第一种 "顺序,用了第二种,先插入员工,但depart_id字段为空,会异常,不能插入

<many-to-one name="depart" column="depart_id" not-null="true"></many-to-one>

  我们来查询一个员工,注意"部门":

//测试查询
public static void main(final String[] args){
    final Employee em = query(7);
    //员工的部门 , 执行Hibernate.initialize()后, 在session关闭前就取得了部门.
    //若没有执行Hibernate.initialize(), 下面会抛异常.
    System.out.println(em.getDepart().getName());
}
//查询一个员工出来
public static Employee query(final int id){
    Session session = null;
    try{
        session = HibernateUtil.getSeesion();
        final Transaction tx = session.beginTransaction();
        final Employee em = (Employee) session.get(Employee.class, id); //按ID查
        //因为 员工的 "部门" 属性会懒加载,
        //在session关闭后,调用em.getDepart()无法取到部门信息
        //所以这里用 Hibernate.initialize(em.getDepart()) 提前加载一下.
        //是em.getDepart() 而不是em
        Hibernate.initialize(em.getDepart());
        tx.commit();
        return em;
    }finally{
        if (session != null){
            session.close();
        }
    }
}

  输出的SQL是:

  Hibernate: select employee0_.id as id1_0_, employee0_.`name` as name2_1_0_, employee0_.depart_id as depart3_1_0_ from Employee employee0_ where employee0_.id=?

时间: 2024-10-09 23:42:30

映射:一对多(部门对员工)和多对一(员工对部门)的相关文章

Hibernate 集合映射 一对多多对一 inverse属性 + cascade级联属性 多对多 一对一 关系映射

1 . 集合映射 需求:购物商城,用户有多个地址. // javabean设计 // javabean设计 public class User { private int userId; private String userName; // 一个用户,对应的多个地址 private Set<String> address; private List<String> addressList = new ArrayList<String>(); //private Str

06章 映射一对多双向关联关系、以及cascade、inverse属性

当类与类之间建立了关联,就可以方便的从一个对象导航到另一个对象.或者通过集合导航到一组对象.例如: 对于给定的Emp对象,如果想获得与它关联的Dept对象,只要调用如下方法 Dept dept=emp.getDept(); //从Emp对象导航到关联的Dept对象 以Dept(部门)类和Emp(员工)类为例: 一.配置双向一对多关联 需在Dept类中增加一个集合类型的emps属性 private Set<Emp> emps=new HashSet<Emp>(); public Se

leetcode185 部门工资前三高的所有员工 Department Top Three Salaries

Employee 表包含所有员工信息,每个员工有对应的 Id,此外还有一列部门 Id. 创建表和数据: Create table If Not Exists Employee (Idint, Name varchar(255), Salary int, DepartmentId int); Create table If Not Exists Department (Idint, Name varchar(255)); Truncate table Employee; insert into E

oracle查询某人所在的部门(326)是否属于部门字符串(329|2)或者该部门字符串的子部门中

部门326为部门329的父部门,部门2与部门326是同级部门: 账户muyunfei,属于329部门 消息发送给部门2及部门326两个部门(326|2),发送的部门对象之间用"|"分割 查询:muyunfei账户是否属于该部门字符串(329|2)或者该部门字符串的子部门中 1.首先使用start with.....connect by获得账户muyunfei的部门及父部门 2.遍历部门及父部门,在循环体重嵌套循环(该循环拆分以"|"为分隔符的部门号),在嵌套的循环体

框架 day32 Hibernate,一级缓存,关联关系映射(一对多,多对多)

一级缓存 概念 *在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java集合构成了Session缓存. 只要 Session 实例没有结束生命周期, 存放在它缓存中的对象也不会结束生命周期 *当session的save()方法持久化一个对象时,该对象被载入缓存, 以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中. 当试图get(). load()对象时,会判断缓存中是否存在该对象,有则返回,此时不查询数据库.没有再查询数据库 *Session 能够在

MyBatis的对象关系映射---一对多等值连接策略★★★★★

在实际开发中,一个业务可能涉及到多个数据表的查询,那么多表查询就涉及连接查询(等值连接), 等值连接 表与表之间有一个外键关键,但是程序中最终获取的表封装的对象, 对象与对象之间是没有外键关系的,对象和对象之间只有依赖关系: 对象之间关系主要是四种: 一对一 关系一个人对应身份证id,一个QQ号对应一个QQ空间 一对多 关系 一个部门对应多个员工 多对一 关系 多个员工对应一个部门 多对多 关系 多个学生对应多个老师,多个学生对应多个课程 什么关系应该从哪个对象作为中心点来看 一对多, 以one

MyBatis的对象关系映射---一对多N+1策略★★★★★

在实际开发中,一个业务可能涉及到多个数据表的查询,那么多表查询就涉及连接查询(等值连接), 等值连接 表与表之间有一个外键关键,但是程序中最终获取的表封装的对象, 对象与对象之间是没有外键关系的,对象和对象之间只有依赖关系: 对象之间关系主要是四种: 一对一 关系一个人对应身份证id,一个QQ号对应一个QQ空间 一对多 关系 一个部门对应多个员工 多对一 关系 多个员工对应一个部门 多对多 关系 多个学生对应多个老师,多个学生对应多个课程 什么关系应该从哪个对象作为中心点来看 一对多, 以one

[原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

【SSH系列】Hibernate映射 -- 一对多关联映射

    映射原理       一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个外键,指向一的一段,关联关系都是在多的一端进行维护,只是我们在写映射的时候发生了变化.       一对多和多对一的映射原理是一样的,但是她们之间也存在着小小的区别,毕竟世界上没有两片完全相同的叶子,她们之间的区别就是维护的关系不同,我们先来看多对一,多端维护一端的关系,在加载多端的时候,可以将一端

JPA学习笔记(8)——映射一对多关联关系

一对多关联关系 本文有很多和多对一是一样的,因此不会写得非常具体. 有看不懂的.能够參考JPA学习笔记(7)--映射多对一关联关系 Order实体类 package com.jpa.helloworld2; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; imp