关于Hibernate的关联关系及其操作
【IT168 技术文档】
三、 对关联关系的对象进行数据库操作
对关联关系的对象进行数据库操作包括级联保存和更新,级联删除以及级联检索,在次,仅以一对多的双向关联为例进行阐述。假设有客户类(Customer类)和订单类(Order类),根据需求建立一对多的双向关联关系,即:一个客户对应多个订单的双向关联关系。
关于Customer和Order的映射文件,在上述一对多/多对一的关系中已经给出,下面代码是Customer映射文件中<set>元素:
<set>元素包括以下属性:<set name="Orders" inverse="true" cascade="save-update">
<key>
<column name="customer_id" not-null="true" />
</key>
<one-to-many class="hibernate.Order" />
</set>
name:设定待映射的持久化类的属性名,这里为Customer类的Orders属性;
cascade:当取值为“save-update”,表示级联保存和更新;
<set>元素还包含两个子元素:<key>和<one-to-many>,其中<key>元素设定与所关联的持久化类对应的表的外键,此处为order表的customer_id字段;<one-to-many>元素设定所关联的持久化类,此处为Order类。
下面列出级联保存和更新、级联删除、级联检索的方法:
级联保存和更新:当设置了cascade属性为“save-update”之后,Hibernate在持久化Customer对象时,会自动持久化所关联的Order对象。代码如下:
级联删除:当cascade属性设为默认值“none”,Hibernate删除一个持久化对象时,不会自动删除与它关联的其他持久化对象,所以在采用级联删除时,可以把cascade设为“all”或者“delete”,这样,Hibernate在删除Customer对象的同时就会自动删除与此关联的Order对象。代码如下:tx=session.beginTransaction();
Customer customer=new Customer();
Order order=new Order();
customer.setName("a");
order.setOrderName("aa");
//建立Customer对象和Order对象的一对多双向关联关系
order.setCustomer(customer);
customer.getOrders().add(order);
session.save(customer);
tx.commit();
在<set>元素还有一个属性inverse,如果将inverse属性值设为“true”,
Hibernate会按照Order对象的状态变化同步更新Customer。代码如下:tx=session.beginTransaction();
//分别加载Customer和Order对象
Customer customer=(Customer)session.get(Customer.class,new
Long(1));
Order order=(Order)session.get(Order.class,new Long(2));
//建立Order和Customer关联关系
order.setCustomer(customer);
session.save(order);
tx.commit();
级联检索:在映射文件中,用<set>元素来配置一对多关联关系,其中在<set>元素中有个lazy和outer-join属性,当lazy属性值设置为false时,表示采用立即检索,当lazy属性值设置为true时,表示采用延迟检索;当outer-join属性值设置为false,表示不采用迫切左外连接检索,如果outer-join属性值设置为true,表示采用迫切左外连接检索方式。tx=session.beginTransaction();
Customer customer=(Customer)session.get(Customer.class,new Long(1));
session.delete(customer);
tx.commit();
● 立即检索:代码如下:
执行session的get()方法时,对于Customer对象采用类级别的立即检索策略,对于与Customer关联的Order对象,采用一对多关联级别的立即检索策略,因此Hibernate执行以下select语句:tx=session.beginTransaction();
Customer customer=(Customer)session.get(Customer.class,new Long(1));
Set orders=customer.getOrders();
Iterator orderIterator=orders.iterator();
tx.commit();
通过以上select语句,Hibernate加载了一个Customer对象和两个Order对象。Customer对象的orders属性引用的是一个Hibernate提供的Set代理类实例,这个代理类实例引用两个Order对象。select * from Customer where id=1;
select * from Order where customer_id=1;
● 延迟检索:假如当一个客户有100个订单,session的get()方法会立即加载一个Customer对象和100个Order对象,但是在很多情况下,应用程序并不需要访问这些Order对象,为此,可以采用延迟检索方式进行检索。此时,应在<set>元素中设置lazy属性值为“true”,代码与立即检索一样,但是程序在执行时却有所区别。此时运行session的get ()方法时,仅立即检索Customer对象,执行如下的select语句:
select * from Customer where id=1;
但是此时Hibernate并没有创建Order代理类实例,get()方法返回的Customer对象的orders属性引用的是Hibernate提供的集合代理类实例,当应用程序第一次访问它,例如调用orders.iterator()方法时,Hibernate会初始化这个集合代理类实例,在初始化过程中到数据库中检索所有与Customer关联的Order对象,执行如下的select语句:
select * from Order where customer_id=1;
采用这种检索方式,便可以在需要的时候才去检索出相应的Order对象,不必要的时候就不用去获得Order对象,大大地节省了资源,也提高了程序的运行效率。
四、 总结:
对象关联关系有一对一、多对一、一对多和多对多。其中一对一关系有两种方式:以主键关联和以外键关联;多对一和一对多关系比较常见,而且分为单向关联和双向关联,通常设置为双向关联,并在“一”这一方设置inverse=“true”(比如上述例子中的Customer);多对多关联需要第三章表来保存两个实体之间的关系。 Hibernate检索策略有立即检索、延迟检索等,对于一对多和多对多的关联,一般设置为延迟检索。
在关联关系中,对象所生成的映射文件中,有<set>元素的各个属性设置。其中cascade属性值包括“none”、“all”等,当cascade设置为“none”表示对一个对象的操作不会影响到相关联的其他对象,当设置为“all”表示对一个对象的所有操作(增加、删除、修改)都会引起相关联的其他对象的操作(增加、删除、修改)。另外还有inverse属性值,它的值设置为“true”表示双方关系仅有对方去维持,一般在一对多的双向关联或者在多对多的关联中使用。
最后,在Hibernate中使用关联关系时,一定要对每一种类型的关联关系写好相对应的映射文件,设置好相应的属性值,建立好对象之间的关系,才能更好的对它们进行数据库的操作。
0
相关文章
