关联关系
类与类之间最普遍的关系就是关联关系
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 ????@Test16 ????public void t2(){17 ????????//工具类18 ????????Session session = HibernateUtil.getSession();19 ????????//开启事务20 ????????Transaction tx=session.beginTransaction();21 ????????//实例化dept22 ????????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 ????@Test35 ????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:list41 ????????????????) {42 ????????????System.out.println("所属员工:"+emps.getEname());43 ????????}44 ????}45 ????//输出指定emps集合中所有emp对象及所关联的部门对象信息46 ????@Test47 ????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:list53 ????????????????) {54 ????????????System.out.println("部门名称:"+emps.getDept().getDname());55 ????????????System.out.println("所属员工为:"+emps.getEname());56 ????????}57 ????}58 ????//;修改编号为1的员工所属部门59 ????@Test60 ????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 ????@Test24 ????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语句以及重复添加数据。
Hibernate关联映射
原文地址:https://www.cnblogs.com/liutao1122/p/8136189.html