Hibernate 映射一对多关联与对象持久化.

映射一对多关联与对象持久化.
一.一对多关联
一对多单向关联的实现:以Customer Order为例
一个customer可以有多个order,而一个order只属于一个客户.
这时order与customer就建立起了n..1的关系.
hibernate中建立单向关联时可以表示为 order(n)--->(1)customer
在java代码中
class Order{
...
private Customer customer;//建立关系
}
class Customer{
...
}
在Order.hbm.xml中
<many-to-one
name='customer'//property
column='customer_id'//关联的字段 与 customer 的主键关联
class='mypack.Customer'
>
</many-to-one>

示例:
Customer customer = new Customer("name");
session.save(customer);//保存客户信息

Order order = new Order();
order.setCustomer(customer);//设置关系
session.save(order);//保存订单信息

级联保存与更新

设置many-to-one 中的cascade = 'save-update'时.则在保存 order 时,会自动去查找临时对象中关联的
Customer对象.然后调用saveOrUpdate方法更新关联的对象.

一对多双向关联
在customer类中,增加set 类保存订单关系,再修改配置文件xml文件,增加关系
class Customer{
...
private Set orders;
}
配置文件 Customer.hbm.xml
增加
<set name='orders'>
<key column='customer_id'></key>//子类的外键
<one-to-many><class>mypak.Order</class></one-to-many>
</set>

同样设置关系时增加 customer.setOrder(new HashSet());
customer.getOrder.add(order);

在设置了cascade = 'save-update' 则在保存时会关联保存customer信息

<set> 元素 inverse属性
在建立了customer 与order双相关联时,则在设置 customer.setOrder(new HashSet());
customer.getOrder.add(order);和order.setCustomer(customer)时,会同时做两次修改
分别做 update order set customer_id = ? where id = ?
和 update customer set customer_id=? and name=? where id = ?
设置完inverse设置为true后.只会设置一个项 update orders.

级联删除
设置 set 的cascade = 'delete' 在删除customer时,同时删除所关联的orders对象.
设置set 的cascade='all-delete-orhpan'时,在删除customer时,会同时删除关联的orders,
在更新customer时,会同时更新orders.

二.一对多双向自身关联
设置category 类 ,类中父类别关联自身.如食物类,包括水果和蔬菜类,梨和香蕉分别属于水果类,西红柿是蔬菜类
class Category{
private Integer cateogryId;
private String name;
private Category parentCategory;
private Set childrenCategorys;
}
配置文件
Category.hbm.xml
<many-to-one>
<name>parentCategory</name>
<column>parent_category_id</column>
<class>mypak.Category</class>
</many-to-one>
<set
name="childrenCategorys"
>
<key>
<column>parent_category_id</column>
</key>
<class>mypak.Category</class>
</set>
1.在设置好各个类之间关系后,可级联保存,前提时在saveOrUpdate时,要能够增加,而设置saveOrUpdate时把对象分为游离对象与临时对象,对临时对象进行保存
而判断时可根据以下几点判断是否为临时对象.
1>首先id为空的,这样就只针对非assigned.
2>或时有设置unsave-value为非空的.这样就只针对非assigned
3>设置version属性.
三.对象持久化
1.flush方法的掉用会直接清理缓存中对象
缓存清理在三种情况下执行,session的查询方法(find,load).session的commit方法,session.flush方法
可以设置缓存的执行模式,session.setFlushMode(FlushMode.Commit);FlushMode.Auto是默认值,表明在find时就可以进行清除了.
2.java对象的状态
1> 临时->持久->游离状态[临时<-持久<-游离状态]
2> 临时对象:
定义:
[1]不处于session缓存中
[2]不存在数据库中
归类:
<1>用new 方法创造的对象
<2>session中delete方法调用删除该对象
3> 持久对象
[1]处于session缓存中的
[2]存数据库中
<1>save.load,find,get方法会使对象持久化
<2>在调用save ,saveOrUpdate,lock方法时会使游离对象转为持久化对象
<3>在级联保存时,会调用方法把关联的临时对象转为持久化对象
4>游离对象
[1]不被session对象关联
[2]游离对象由持久化对象转变,数据库可能保存该记录.
[3]new 以后设置的主键与数据库中关联
<1>sessoin调用close方法时,
<2>sessoin调用evict方法时.
3.session的保存,更新,删除,查询方法
1>save方法,使一个对象由临时对象转变为持久对象
[1]当id 配置为increment自动增长时,外部设置对象的id是没有意义的
[2]当对象已被持久化(save方法)后,修改对象的id是不允许的
[3]当两个customer对象被一个session保存后变为游离状态,再由另一个 session保存时,是以允许的,但在业务是存在两条相同记录,是没有意义的.
2>update方法,使一个游离对象变为一个持久对象
[1]当设置多个更新方法时,update不会马上更新,只有在最后flush时才更新,这样就保证不会因为每次都更新而影响性能
[2]当载完一个游离对象后.不进行操作,而调用update方法时,会进行update语句操作,可以设置class的select-before-update方法进行一次判断.
在调用比较少的情况下进行此操作,否则影响性能
[3]当一个session加载完一个游离对象时,另一个session又加载该对象,且调用update保存游离对象时会报错.
3>saveOrUpdate方法,
1.当对象是临时对象时,调用save,当对象时游离时,调用update,当对象是持久化对象则返回(如果持久化对象更新则属游离状态)
判断是否临时对象:
[1]oid为null
[2]version为null
[3]oid的值为unsave-value
[4]vesion的值为unsave-value
[5]自定义interceptor
4>load,get方法,从数据库中加载一个持久化对象,唯一区别就是load方法加载不存在数据时抛异常而get不抛异常,返回一个null.
5>delete 方法传入一个持久化对象,之后使该对象变为临时状态.如果传入游离状态后则,先持久化对象再删除.

触发器:timestamp自动保存信息
拦截器.继承Interceptor接口,在config时要先设置这个拦截器.最好用两个不同session来处理栏截器事务与正常事务.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值