zoukankan      html  css  js  c++  java
  • 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语句以及重复添加数据。

  • 相关阅读:
    Codeup
    IDEA基于Maven Struts2搭建配置及示例
    深入理解HTTP协议、HTTP协议原理分析
    25条提高iOS App性能的技巧和诀窍
    怎么在苹果Mac虚拟机上安装Win7
    app让个别界面横屏,其他的为竖屏,解决如下
    设置控制器,出现默认知道空隙
    论项目采购管理
    hybrid app
    iOS中使用 Reachability 检测网络
  • 原文地址:https://www.cnblogs.com/liutao1122/p/8136189.html
Copyright © 2011-2022 走看看