Hibernate:如何映射聚合?

Hibernate:如何映射聚合?

目录

背景映射聚合聚合模型映射配置测试备注

背景返回目录

DDD 是在 Hibernate 之后发现的概念,Hibernate 如何映射 DDD 中的聚合呢?本文给出一种思路。

参考资料:DDD:使用EntityFramework的话,如果只为聚合根设计仓储,其它实体如何处理?

映射聚合返回目录

聚合模型返回目录

Order

复制代码
 1 package model;
 2 
 3 import java.util.*;
 4 
 5 public class Order {
 6     private Integer orderId;
 7     private String customer;
 8     private Set<OrderItem> orderItems = new HashSet<OrderItem>();
 9 
10     public Integer getOrderId() {
11         return orderId;
12     }
13 
14     public void setOrderId(Integer orderId) {
15         this.orderId = orderId;
16     }
17 
18     public String getCustomer() {
19         return customer;
20     }
21 
22     public void setCustomer(String customer) {
23         this.customer = customer;
24     }
25 
26     public Set<OrderItem> getOrderItems() {
27         return orderItems;
28     }
29 
30     public void setOrderItems(Set<OrderItem> orderItems) {
31         this.orderItems = orderItems;
32     }
33 
34 }
复制代码

OrderItem

复制代码
 1 package model;
 2 
 3 import java.io.Serializable;
 4 
 5 public class OrderItem implements Serializable {
 6     private static final long serialVersionUID = 8584993780461202406L;
 7     private Integer orderId;
 8     private Integer productId;
 9     private String product;
10 
11     public Integer getProductId() {
12         return productId;
13     }
14 
15     public void setProductId(Integer productId) {
16         this.productId = productId;
17     }
18 
19     public String getProduct() {
20         return product;
21     }
22 
23     public void setProduct(String product) {
24         this.product = product;
25     }
26 
27     public Integer getOrderId() {
28         return orderId;
29     }
30 
31     public void setOrderId(Integer orderId) {
32         this.orderId = orderId;
33     }
34 }
复制代码

映射配置返回目录

Order

复制代码
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3                                    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2013-10-7 21:33:57 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping>
 6  <class name="model.Order" table="Orders">
 7   <id name="orderId" type="java.lang.Integer">
 8    <column name="OrderId"/>
 9    <generator class="identity"/>
10   </id>
11   <property generated="never" lazy="false" name="customer" type="java.lang.String">
12    <column name="Customer"/>
13   </property>
14   <set cascade="all,delete-orphan" inverse="true" lazy="true"
15    name="orderItems" sort="unsorted" table="OrderITems">
16    <key>
17     <column name="OrderId"/>
18    </key>
19    <one-to-many class="model.OrderItem"/>
20   </set>
21  </class>
22 </hibernate-mapping>
复制代码

OrderItem

复制代码
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3                                    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2013-10-7 21:33:57 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping>
 6  <class name="model.OrderItem" table="OrderItems">
 7   <composite-id>
 8    <key-property name="orderId">
 9     <column name="OrderId"/>
10    </key-property>
11    <key-property name="productId">
12     <column name="ProductId"/>
13    </key-property>
14    <generator class="assigned"/>
15   </composite-id>
16   <property generated="never" lazy="false" name="product" type="java.lang.String">
17    <column name="Product"/>
18   </property>
19  </class>
20 </hibernate-mapping>
复制代码

重点注意:Order 的 set 指定了 cascade="all 和 delete-orphan" inverse="true",OrderItem 使用了双主键(不是必须的)。

测试返回目录

代码

复制代码
 1 package demo;
 2 
 3 import model.*;
 4 
 5 import org.hibernate.*;
 6 
 7 /*
 8  * 测试 聚合设计。
 9  */
10 public class AggregateDemo implements Demo {
11 
12     @Override
13     public void run() {
14         SessionHelper.execute(new SessionAction() {
15 
16             @Override
17             public void action(Session session) {
18                 Order order = new Order();
19                 order.setCustomer("段光伟");
20                 session.save(order);
21                 
22                 OrderItem item = new OrderItem();
23                 item.setOrderId(order.getOrderId());
24                 item.setProductId(1);
25                 item.setProduct("苹果");
26                 order.getOrderItems().add(item);
27             }
28 
29         });
30 
31          SessionHelper.execute(new SessionAction() {
32         
33          @Override
34          public void action(Session session) {
35          Order order = (Order) session.get(Order.class, new Integer(1));
36          order.getOrderItems()
37          .remove(order.getOrderItems().toArray()[0]);
38          }
39         
40          });
41     }
42 }
复制代码

输出SQL

复制代码
 1 begin transaction
 2 action
 3 Hibernate: 
 4     /* insert model.Order
 5         */ insert 
 6         into
 7             Orders
 8             (Customer) 
 9         values
10             (?)
11 flush and commit
12 Hibernate: 
13     /* get current state model.OrderItem */ select
14         orderitem_.OrderId,
15         orderitem_.ProductId,
16         orderitem_.Product as Product3_16_ 
17     from
18         OrderItems orderitem_ 
19     where
20         orderitem_.OrderId=? 
21         and orderitem_.ProductId=?
22 Hibernate: 
23     /* insert model.OrderItem
24         */ insert 
25         into
26             OrderItems
27             (Product, OrderId, ProductId) 
28         values
29             (?, ?, ?)
30 begin transaction
31 action
32 Hibernate: 
33     /* load model.Order */ select
34         order0_.OrderId as OrderId1_17_0_,
35         order0_.Customer as Customer2_17_0_ 
36     from
37         Orders order0_ 
38     where
39         order0_.OrderId=?
40 Hibernate: 
41     /* load one-to-many model.Order.orderItems */ select
42         orderitems0_.OrderId as OrderId1_17_1_,
43         orderitems0_.OrderId as OrderId1_16_1_,
44         orderitems0_.ProductId as ProductI2_16_1_,
45         orderitems0_.OrderId as OrderId1_16_0_,
46         orderitems0_.ProductId as ProductI2_16_0_,
47         orderitems0_.Product as Product3_16_0_ 
48     from
49         OrderItems orderitems0_ 
50     where
51         orderitems0_.OrderId=?
52 flush and commit
53 Hibernate: 
54     /* delete model.OrderItem */ delete 
55         from
56             OrderItems 
57         where
58             OrderId=? 
59             and ProductId=?
复制代码

备注返回目录

还有几个问题还没有深入想:

  1. 如何聚合的关联层次很大,聚合根之外的实体的主键的数量也需要相应的增加,开发是否方便呢?还无从验证。
  2. 是否有必要为聚合根之外的实体引入一个逻辑主键,这种模式只有 Hibernate 支持,EntityFramework 就不支持。
  3. 使用 bag + composite-element 是否也可以?效率会不会太低。

希望朋友们多给点建议。

 
分类: Hibernate
原文地址:https://www.cnblogs.com/Leo_wl/p/3356998.html