Hibernate关联映射

关联关系

类与类之间最普遍的关系就是关联关系

hibernate中的关联关系有四种:一对一、一对多、多对一、多对多。
 
关联关系中又分为单向关联与双向关联
关联关系中又分为单向关联与双向关联
 
单向关联:单向关联是指只有一方有另一方的关联信息而另一方没有关联信息               例:
 A——>B 
 A对象中有B对象的关联信息
 
 B对象中没有A对象的关联信息
 
我们可以通过A对象中B的关联信息查询或修改B对象的信息但无法通过B对象来查询修改A对象的信息
 
同理A<——B也是单向关联
 
这种只是单方面的关联我们称为单向关联
 
双向关联:双向关联是指两方都有另一方的关联信息
例:
 A<——>B
A对象中有B对象的关联信息
B对象中也有A对象的关联信息
我们可以通过A对象中B的关联信息查询或修改B对象的信息也可以通过B对象来查询修改A对象的信息
 
这种两方都有另一方的关联信息我们称为双向关联
 
单向关联一般在一方配置多方不进行配置
  如:一对多 单向关联在“一”的一方配置文件里进行配置,"多"的一方不进行配置
双向关联两方都要配置
  如:一对多 双向关联在“一”的一方配置文件里需要配置,“多”的一方也需要进行配置

 多对一单向关联

Dept:

1 public class Dept {
2     private Integer deptno;
3     private String dname;
4 }

Dept.hbm.xml:

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 
 6 <hibernate-mapping package="cn.hibernate.day04mapping.manytoone">
 7     <!--实体 name=实体端内容  column=DB端内容-->
 8     <class name="Dept" table="DEPT" dynamic-update="true" schema="liutao">
 9         <!--底层数据表对应的主键-->
10         <id name="deptno" column="DEPTNO">
11             <!--主键生成策略: assigned  程序员手动给值-->
12             <generator class="native"/>
13         </id>
14         <property name="dname" column="DNAME"></property>
15     </class>
16 
17 </hibernate-mapping>

Emp:

1 public class Emp {
2   private Integer empno;
3   private String ename;
4   private Dept dept;
5 }

Emp.hbm.xml

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="cn.hibernate.day04mapping.manytoone">
 6     <!--实体 name=实体端的内容   column=DB端的内容-->
 7     <class name="Emp" table="EMP" schema="liutao">
 8         <!--和底层数据表对应的主键   业务意义-->
 9         <id name="empno" column="EMPNO">
10            <generator class="native"></generator>
11         </id>
12         <property name="ename" column="ENAME"></property>
13         <many-to-one name="dept" class="Dept" column="deptno"></many-to-one>
14     </class>
15 </hibernate-mapping>

单元测试:

 1   //关联查询 多对一单项关联
 2     @Test
 3     public void t1(){
 4         //工具类
 5         Session session = HibernateUtil.getSession();
 6         //提供一个员工编号
 7         Emp emp = session.load(Emp.class, 20);
 8         System.out.println(emp);
 9        System.out.println(emp.getEname());
10         //员工所属部门
11        System.out.println(emp.getDept().getDname());
12     }
13 
14    //保存部门和员工
15     @Test
16     public void t2(){
17         //工具类
18         Session session = HibernateUtil.getSession();
19         //开启事务
20         Transaction tx=session.beginTransaction();
21         //实例化dept
22         Dept dept=new Dept();
23         dept.setDname("后勤部666");
24         Emp emp=new Emp();
25         emp.setEname("孙俪");
26         //设置员工所属的部门
27         emp.setDept(dept);
28         session.save(dept);
29         session.save(emp);
30         tx.commit();
31         session.close();
32     }
33     //按照指定的部门对象查询相关的员工对象
34     @Test
35     public void t3(){
36         Session session = HibernateUtil.getSession();
37         String hql="from Emp e where e.dept.deptno=15";
38         Query query = session.createQuery(hql);
39         List<Emp> list = query.list();
40         for (Emp emps:list
41                 ) {
42             System.out.println("所属员工:"+emps.getEname());
43         }
44     }
45     //输出指定emps集合中所有emp对象及所关联的部门对象信息
46     @Test
47     public void t4(){
48         Session session = HibernateUtil.getSession();
49         String hql="from Emp";
50         Query query = session.createQuery(hql);
51         List<Emp> list = query.list();
52         for (Emp emps:list
53                 ) {
54             System.out.println("部门名称:"+emps.getDept().getDname());
55             System.out.println("所属员工为:"+emps.getEname());
56         }
57     }
58     //;修改编号为1的员工所属部门
59     @Test
60     public void t5(){
61         //工具类
62         Session session = HibernateUtil.getSession();
63         //开启事务
64         Transaction tx=session.beginTransaction();
65         Emp emp = session.load(Emp.class, 18);
66         Dept dept=new Dept();
67         dept.setDeptno(15);
68         emp.setDept(dept);
69         dept.getEmps().add(emp);
70         tx.commit();
71 
72         session.close();
73     }

一对多双向关联

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.hibernate.day04mapping.manytoonedouble">
    <!--实体 name=实体端内容  column=DB端内容-->
    <class name="Dept" table="DEPT" dynamic-update="true" schema="liutao">
        <!--底层数据表对应的主键-->
        <id name="deptno" column="DEPTNO">
            <!--主键生成策略: assigned  程序员手动给值-->
            <generator class="native"/>
        </id>
        <property name="dname" column="DNAME"></property>
        <set name="emps" cascade="save-update" inverse="false">
            <key column="deptno"></key>
            <one-to-many class="Emp"></one-to-many>
        </set>
    </class>

</hibernate-mapping>

Emp.hbm.xml

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="cn.hibernate.day04mapping.manytoonedouble">
 6     <!--实体 name=实体端的内容   column=DB端的内容-->
 7     <class name="Emp" table="EMP" schema="liutao">
 8         <!--和底层数据表对应的主键   业务意义-->
 9         <id name="empno" column="EMPNO">
10            <generator class="native"></generator>
11         </id>
12         <property name="ename" column="ENAME"></property>
13         <many-to-one name="dept" class="Dept" column="deptno"></many-to-one>
14     </class>
15 </hibernate-mapping>

单元测试:

 1  @Test
 2     public void t6(){
 3         //通过部门查询该部分下所有员工信息(设置从部门到员工的一级关联)
 4         String hql="from Dept";
 5         Session session = HibernateUtil.getSession();
 6         Query query = session.createQuery(hql);
 7         List<Dept> list = query.list();
 8         for (Dept item:list
 9              ) {
10             System.out.println("========================");
11             System.out.println(item.getDname());
12             for (Emp emps:item.getEmps()
13                  ) {
14                 System.out.println(emps.getEname());
15             }
16             System.out.println("===========END==============");
17         }
18         //通过某个员工获取员所在部门(设置从员工到部门的多对一关联)
19         Emp emps = session.load(Emp.class, 18);
20         System.out.println(emps.getDept().getDname());
21     }
22     //添加部门同时添加员工
23     @Test
24     public void t7(){
25        Session session = HibernateUtil.getSession();
26       Transaction tran = session.beginTransaction();
27       //准备一个emp对象
28        Dept dept=new Dept();
29       dept.setDname("餐饮部");
30       //准备一个emp对象
31       Emp emp=new Emp();
32       emp.setEname("张三");
33       dept.getEmps().add(emp);
34       session.save(dept);
35      // 事务提交
36      tran.commit();
37    }

 

关联标记属性

简单介绍下面几个,除了name是必须,其余都是可选的。更多的我们参考官文档。

name="植入集合的集合名"

column="映射到本表的字段名"

class="映射到本表的实体类"

unique="ture|false":(数据库外键字段生成一个唯一约束)

not-null="ture|false"默认false(数据库外键字段是否允许为空值)

lazy="ture|false"默认proxy(延迟加载)

关于cascade(级联)属性

级联的意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作

总共可以取值为:all、none、save-update、delete

all-代表在所有的情况下都执行级联操作

none-在所有情况下都不执行级联操作

save-update-在保存和更新的时候执行级联操作

delete-在删除的时候执行级联操作

 inverse属性

 反转,主要用在一对多,多对对双向关联上,inverse可以设置到<set>集合上, 默认inverse为false。为true表示反转,由对方负责;反之,不反转,自己负责;如果不设,one和many两方都要负责控制,因此,会引发重复的sql语句以及重复添加数据。

原文地址:https://www.cnblogs.com/liutao1122/p/8136189.html