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

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来处理栏截器事务与正常事务.