【学习笔记】Hibernate关联映射(Y2-1-6)
Hibernate关联映射
关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用。
1.单向多对一关联
准备数据库
部门表和员工表
其中部门表有两列 部门编号和名称
员工表有三列 员工ID 名称 和对应的部门id
部门和员工是一个1:N的关系(一个部门有多个员工 一个员工属于一个部门)
Hibernate 小配置文件
<class name="Emp" table="EMP"> <id name="empId" type="java.lang.Integer"> <!--主键生成策略--> <generator class="native"/> </id> <property name="empName" type="string"/> <!--置入一个Dept对象: 多对一--> <many-to-one name="dept" class="Dept" column="deptNo"></many-to-one> </class>
在员工EMP的小配置文件中加入many-to-one标签
name属性是EMP实体类中的存放部门的集合的名称
实体类代码如下
然后就配置完了((
书写测试类
Session session; Transaction tx; @Before public void myBefore(){ session=HibernateUtil.currentSession(); tx=session.beginTransaction(); } @After public void myAfter(){ tx.commit(); HibernateUtil.closeSession(); } //修改编号为22的员工所属的部门 @Test public void updateEmpToOtherDept(){ Emp emp = session.load(Emp.class, 22); Dept dept=session.load(Dept.class,28);//上下文跟踪到 emp.setDept(dept); session.saveOrUpdate(emp); } //2.按照指定的部门对象28,查询相关的Emp对象 @Test public void selectEmpsByDeptId(){ String hql="from Emp where dept.deptNo=28"; Query query = session.createQuery(hql); List<Emp> list = query.list(); for (Emp emp:list) { System.out.println(emp.getEmpName()); } } //输出指定的emps集合中的所有emp对象及其所关联的部门对象的信息 @Test public void selectEmpInfo(){ String hql="from Emp"; Query query = session.createQuery(hql); List<Emp> list = query.list(); for (Emp emp:list) { System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName()); } }
2.双向一对多关联
依然是我们的部门表DEPT和员工表EMP
我们就不做截图了
现在实体类中
Dept部门中保存着一个员工的集合
Emp员工中也存放着一个Dept对象 关联着的是对应的部门
部门的实体类如下
Hibernate小配置文件
<class name="Dept" table="DEPT"> <id name="deptNo" type="java.lang.Integer"> <!--主键生成策略--> <generator class="native"/> </id> <property name="deptName" type="string"/> <!--一对多配置 一个部门有N个员工--> <set name="emps" cascade="save-update" inverse="true"> <key column="deptNo"></key><!--多的一方的外键--> <one-to-many class="Emp"/> </set> </class>
在关联员工的Set集合时 使用Set标签
name属性对应实体类中的集合名称
key标签是一对多中多的一方的外键 对应的列是部门的编号
one-to-many表示一对多 关联的实体类是Emp员工类
Set标签的其他属性说明
1.cascade属性
当几个对象需要级练操作的时候可以使用该属性
适用场景:当小配置需要反馈对象间关系
2.inverse属性指定了关联关系中的方向
1.inverse设置为false 则为主动方,由主动方负责维护关联关系 ,默认是false
2.inverse设置为true,不负责维护关联关系
//inverse属性建议设置为true
//在建立两个对象的双向关联时,应该同时修改关联两端的对象的相应属性
3.order-by
书写测试类
@Test public void manyToOneDouble(){ Session session= HibernateUtil.currentSession(); Transaction tx=session.beginTransaction(); Dept dept=new Dept(); dept.setDeptName("17"); Emp emp=new Emp(); emp.setEmpName("天命"); emp.setDept(dept); //dept.getEmps().add(emp); session.save(dept); session.save(emp); tx.commit(); HibernateUtil.closeSession(); }
延迟加载
延迟加载(lazy load)是当在真正需要数据时,才执行SQL语句进行查询 避免了无谓的开销
<class name="Dept" table="DEPT" lazy="true/false">
(默认lazy为true)
lazy属性只对load()方法有效 (对get无效)
类级(当前类中)
2.关联级别
<set name="emps" lazy="true/false/extra" lazy="true" cascade="save-update" inverse="true">
<key>
<column name="DEPTNO"></column>
</key>
<......>
</set>
lazy="true/false/extra"
true:延迟加载
false:立即加载
extra:扩展(极其懒惰)