将Java Domain对象映射到Tables的好设计(使用Hibernate)

时间:2010-05-20 08:34:02

标签: java hibernate database-design orm domain-driven-design

我有一个问题,更多的是在设计领域,而不是实施。 我也很高兴有人指出答案的资源,我很乐意, 为自己研究。

高度简化的Java和SQL:

假设我有一个名为'Picture'的业务域POJO,它有三个属性。

class Picture
     int idPicture
     String fileName
     long size

假设我有另一个名为“Item”的业务域POJO,其中包含3个属性

 class Item
     int idItem
     String itemName
     ArrayList<Picture> itemPictures

这些是一种正常的简单关系。你可以说'图片'对象,会 永远不会出现在'Item'对象之外。假设图片仅属于特定项目,但是 一个项目可以有多个图片

现在 - 使用良好的数据库设计(第3范式),我们知道应该放置物品和 他们自己的桌子上的图片。这是我认为是正确的。

 table Item
     int  idItem  (primary key)
     String  itemName 

 table Picture
     int   idPicture (primary key)
     varchar(45) fileName
     long  size
     int  idItem  (foreign key)

这是我的问题: 如果您正在为这些对象制作Hibernate映射文件。在数据设计中,您的 图片表需要一个列来引用Item,以便外键关系可以 保持。 但是,在您的业务域对象中 - 您的Picture对象不包含 项的idItem的引用/属性 - 并且不需要知道它。始终是Java图片实例 在Item实例中实例化。如果您想知道图片所属的项目 你已经在正确的范围内。调用myItem.getIdItem()和myItem.getItemPictures(),您就拥有了所需的两条信息。

我知道Hibernate工具有一个可以自动让你的POJO看起来的生成器 在你的数据库。 我的问题源于我为此计划了数据设计的事实 实验/项目第一。然后,当我去创建域java对象时,我意识到了这一点 好的设计决定了对象以嵌套的方式保存其他对象。这显然是 不同于数据库模式的方式 - 所有对象(表)都是扁平的 其中不包含其他复杂类型。什么是调和这个的好方法?

你愿意:

(A)制作hibernate映射文件,使Picture.hbm.xml具有到POJO的映射 parent的idItem字段(如果它甚至可能)

(B)在Picture类中添加一个int属性来引用idItem并在实例化时设置它,从而通过将所有表字段作为类中的本地属性来简化hbm.xml映射文件

(C)修复数据库设计,因为它错了,dork。

我真的很感激任何反馈

4 个答案:

答案 0 :(得分:3)

在我看来,你Picture中并不需要任何引用其Item的内容,因为你说Item当你拥有Picture<class name="Item"> <id name="id" column="item_id"/> .... <set name="pictures" inverse="true"> <key column="item_id"/> <one-to-many class="Picture"/> </set> </class> <class name="Picture"> <id name="id" column="picture_id"/> .... <many-to-one name="item" class="Item" column="item_id" not-null="true"/> </class> 1}}。

但如果事实证明你真的需要这个参考,那就是设置双向一对多关联的情况。

看看这是如何完成的:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/collections.html

示例:

{{1}}

答案 1 :(得分:0)

您需要修改您的图片表以保存对项目表的引用,然后您可以存储多个项目图片。

对于hibernate映射,您可以在主对象(Item)的hbm文件中映射一组依赖对象(图片)。它被称为组件映射。

您可以查看休眠指南:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/components.html#components-incollections

答案 2 :(得分:0)

我不确定这背后的xml配置,但是使用注释你可以做这样的事情(JPA 2.0):


@Embeddable
class Picture
  int id
  String filename
  long size

class Item
  int idItem
  String itemName

  @ElementCollection
  @CollectionTable(name = "item_picture", joinColumns = @JoinColumn(name = "item_id"))
  List<Picture> pictures

答案 3 :(得分:0)

该协会还有其他属性吗?如日期,状态等?如果是这样,我会将其建模为:

 table Item
     int  idItem  (primary key)
     String  itemName 

 table Picture
     int   idPicture (primary key)
     varchar(45) fileName
     long  size

 table ItemPictureAssociation
     int   idItem (foreign key)
     int   idPicture (foreign key)
     int   sequence (composite PK)
     <other columns>

通过这种方式,您可以保持一对多关系,将两个对象自己的详细信息分开,并在需要时维护关系的属性。