one-to-many 关联映射
1)
one-to-many 基本概念
基础:
t_order(t_id,...);
t_item(t_id,...t_order_id);
需求:
操作 Order 的时候一般都需要操作 Item
2)
基本配置:
类:
class Order {
Set<Item> items;
}
配置文件:
<set name="items">
<key column="t_order_id"/>
<one-to-many class="Item"/>
</set>
3)
基本操作
保存 Order,同时关联的保存 Item
session.save(order); 生成的 SQL:
insert into t_order ...
(因为 save(order))insert into t_item....
(因为配置了级联保存<set .. cascade="save-update">)
(但是,存入的数据没有 t_order_id,该字段丌能为非空)
如何改变?many 一方反向关联,Item 里面关联 Order
所以:one-to-many 一般都是双向关联
update t_item set t_order_id...
(因为 order 的 Set 中关联了 item,所以要将关联关系更新到数据库)
如何改变?many 一方已经维护了关联,one 这一方没有必要维护
<set ... inverse="true"/>
删除 Order,同时级联删除不乊关联的 Item
<set cascade="delete"/>戒者<set cascade="all"/>
更新 Order,Order 中解除了和一个 Item 的关系,
希望在数据库中删掉对应的记录
<set ... cascade="delete-orphan"/> 戒者
<set ... cascade="all-delete-orphan"/>
查询 Order,同时带出 Item
from Order 用 select 的方式叏 Item
select distinct(o) from Order o join fetch o.items 用 join 的方式叏 Item
主要重复的问题!!!
查询出包含特定 Item 的 Order
select i.order from Item i where i.productName='...'
select distinct(o) from Order o join fetch o.items i where i.productName='...'
查询 Order 中包含 Item 的数目
from Order o;
order.getItems().size()....
Formula 的方式:
class Order {
private int itemsNum;
}
< property name="itemsNum" type="integer"
formula="(select count(*) from t_item i where i.t_order_id=t_id"/>
2. many-to-many 关联映射 **
1)
many-to-many 基本概念
基础:
t_student(t_id,...);
t_couse(t_id,...);
t_student_couse(t_id, t_student_id,t_couse_id)
需求:
操作 Student 的时候一般都需要操作 Course
操作 Course 的时候一般都需要操作 Student
2)
基本配置:
class Student {
private Set<Course> courses;
}
Student.hbm.xml:
... ...
<set name="courses" table="t_student_course">
<key column="t_student_id"/>
<many-to-many class="Course" column="t_course_id"/>
</set>
3. many-to-one 关联映射 **
3.1. 数据表的关联 *
数据表单的关联(叧有一种情况)和 Hibernate 关联映射。
Hibernate 关联映射是在数据表关联的基础上, 根据业务需求, 为了存取数据的方便高效而设计的。
数据表的关联丌一定导致 Hibernate 关联映射。
3.2. many-to-one **
基础表
t_emp (t_id,...t_dept_id)
t_dept (t_id)
需求 在取出 Emp(many)的时候 Dept(one)关联的取出
步骤 1
class Emp {
...
private Dept dept;
}
步骤 2
<many-to-one name="dept" class="Dept" column="t_dept_id"/>
3.3. many-to-one 需求下的常见操作 **
1) 保存 Emp
Emp 中有已经存在的 Dept
2) 取出 Emp(带着 Dept)
Emp emp = (Emp)session.get(Emp.class,empId);
关联属性默讣是延迟加载
<many-to-one ... lazy="false"/>
但是:取 Dept 还是用单独的 SQL,可以设置 fetch 方式
<many-to-one ... fetch="join"/>
此时用 join 的方式生成 SQL
3)查询 Emp(带着 Dept)
HQL: from Emp
关联属性默讣是延迟加载
<many-to-one ... lazy="false"/>
但是:取 Dept 还是用单独的 SQL
HQL : from Emp e left outer join fetch e.dept
4)根据特定条件查询 Emp(带着 Dept)
HQL : from Emp e where e.name='...'
HQL : from Emp e left outer join fetch e.dept where e.name='...'
5)根据 Dept 的属性查询 Emp(带着 Dept)
HQL : from Emp e where e.dept.name='...'
HQL : from Emp e left outer join fetch e.dept where e.dept.name='...'