zoukankan      html  css  js  c++  java
  • 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 是否也可以?效率会不会太低。

    希望朋友们多给点建议。

  • 相关阅读:
    03.友盟项目--原始日志数据生成(改进版)---redis存储 用户设备的信息
    Java中的字符集
    时间复杂度
    Hive建模
    08、Spark常用RDD变换
    06、部署Spark程序到集群上运行
    05、Spark
    04、Spark Standalone集群搭建
    02、体验Spark shell下RDD编程
    03、IDEA下Spark API编程
  • 原文地址:https://www.cnblogs.com/happyframework/p/3356498.html
Copyright © 2011-2022 走看看