1.双向关联操作示例:
1)用户POJO和订单POJO:
2)POJO.hbm.xml:
<!-- PojoOrder.hbm.xml -->
<hibernate-mapping package="cn.cvu.hibernate.domain">
<class name="PojoOrder" table="tb_order" select-before-update="true">
<id name="id" column="t_id" type="int">
<generator class="native"></generator>
</id>
<property name="addr" column="t_addr"></property>
<property name="totalprice" column="t_totalprice"></property>
<!-- 一个订单对应一个用户
name=订单类中的用户属性
class=用户类路径
column=生成的保存用户id的列
-->
<many-to-one
name="user"
class="cn.cvu.hibernate.domain.PojoUser" column="t_user_id"/>
</class>
</hibernate-mapping>
-----------------------------------------------------------------------------------------------------------------
<!-- PojoUser.hbm.xml -->
<hibernate-mapping package="cn.cvu.hibernate.domain">
<class name="PojoUser" table="tb_user" select-before-update="true">
<id name="id" column="t_id" type="int">
<generator class="native"></generator>
</id>
<property name="name" column="t_name"></property>
<property name="age" column="t_age"></property>
<property name="city" column="t_city"></property>
<!-- set即PojoUser中表单变量类型。name=表单变量名 -->
<set name="orders">
<!-- column=对应的订单表中的列,
即PojoOrder.hbm.xml中的<many-to-one>的column="t_user_id">
-->
<key column="t_user_id"/>
<!-- 一个用户对应多个订单。
class="表单类"
-->
<one-to-many class="cn.cvu.hibernate.domain.PojoOrder"/>
</set>
</class>
</hibernate-mapping>
3)hibernate.cfg.xml:
4)操作:
public void test() {
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
//创建用户
PojoUser user = new PojoUser();
user.setName("Akon");
user.setAge(44);
user.setCity("USA");
//创建订单1
PojoOrder order1 = new PojoOrder();
order1.setAddr("Detroit");
order1.setTotalprice(334);
//创建订单2
PojoOrder order2 = new PojoOrder();
order2.setAddr("Los Angeles");
order2.setTotalprice(232);
//关联用户表中的订单。user级联order
user.getOrders().add(order1);
user.getOrders().add(order2);
//关联订单中的用户。order级联user
order1.setUser(user);
order2.setUser(user);
//保存全部相关数据
session.save(user);
session.save(order1);
session.save(order2);
transaction.commit();
session.close();
}
5)结果:
6)异常:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cn.cvu.hibernate.domain.PojoOrder
2.关联表单的级联保存:
针对上面的TransientObjectException错误。
常见级联操作:增加save-update、修改save-update、删除delete 。
例:save用户,自动同时保存订单:
1)PojoUser.hbm.xml配置:
在多表关联配置中增加cascade属性。
2)操作:
3.级联删除:
1)基本操作:
public void test() {
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
//脱管对象
PojoUser user1 = new PojoUser();
user1.setId(3);
session.delete(user1);
//持久对象
PojoUser user2 = (PojoUser) session.get(PojoUser.class, 4);
session.delete(user2);
transaction.commit();
session.close();
}
2)配置POJO.hbm.xml:
3)级联删除操作:
4.孤子删除:
通过操作User对象,删除Order对象,将用户的订单从数据表删除。
1)POJO.hbm.xml:
使用用户删除订单,则在用户的hbm文件配置。
2)操作:
public void test(){
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
//持久化对象 用户
PojoUser user = (PojoUser) session.get(PojoUser.class, 2);
//持久化对象 订单
PojoOrder order = (PojoOrder) session.get(PojoOrder.class, 3);
//用户删除订单集合中的某条订单
user.getOrders().remove(order);
transaction.commit();
session.close();
}
3)结果:
4)未配置hbm时的操作结果:
5.外键修改权的配置:
1)POJO.hbm.xml:
2)操作:
public void test(){
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
//持久化对象 用户1
PojoUser user = (PojoUser) session.get(PojoUser.class, 1);
//持久化对象 订单6,原属用户3
PojoOrder order = (PojoOrder) session.get(PojoOrder.class, 6);
//更新第6条订单的用户。已配置双向级联
user.getOrders().add(order); //放弃更新订单表的外键inverse=true。此句无意义
order.setUser(user);
transaction.commit();
session.close();
}
3)结果:
仅有一条update语句。
6.一对多中的父子关系:
一的一方理解为父方,多的一方理解为子方。
1)在父方设置cascade-级联:
(1)save-update:级联保存
(2)delete:级联删除
(3)delete-orphan:孤儿删除
2)在父方设置inverse-逆转职能:
true:将外键维护权完全由子方行使。
3)inverse和cascade的区别:
cascade 级联,cascade="save-update" 保存A时级联保存B
inverse 外键列值维护权利inverse=true 放弃权利,无法设置外键列的值
- end