M. *_*her 8 java mapping hibernate
我有一个场景的"最佳实践"问题.
场景:数据库中的多个实体,例如Document,BlogPost,Wiki可以由个人共享.不是为每个实体创建共享表,而是创建单个共享表.问题是,如何使用不同的实体映射共享表?
我有三个选项,请告知哪个选项最好,以及是否有更好的选择.
选项1: 创建表共享为:
SHARES
id (unique)
entityId (non DB enforced FK to DOCUMENTS, WIKIS, POSTS etc.)
entityType
sharedBy
sharedWith
sharedDate
Run Code Online (Sandbox Code Playgroud)
这里,entityId将是documentId,wikiId,postId等的FK,entityType将识别entityId的类型.
在创建共享到实体映射时,这在Hibernate建模中存在问题,例如share.getDocument()或share.getWiki()等.
选项2: 创建仅包含共享信息的表共享,然后创建将共享绑定到实体的解析表.
SHARES
id(PK)
sharedBy
sharedWith
sharedDate
shareType (helper field for searches)
SHARES_DOCUMENTS
share_id (unique ID and FK, one to one with SHARES)
document_id (FK to DOCUMENTS)
SHARES_POST
share_id (unique ID and FK, one to one with SHARES)
post_id (FK to POSTS)
more share tables here.
Run Code Online (Sandbox Code Playgroud)
因此,hibernate明智地,Share可以为每个共享类型一对一(例如share.getDocument(),share.getPost(),并且shareType将标识哪个关系是'活动')
选项3 与选项1类似,但创建单个列而不是实体ID
SHARES
id (unique ID)
documentId (FK to DOCUMENTS, nullable)
postId (FK to POSTS, nullable)
wikiId (FK to WIKIS, nullable)
sharedBy
sharedWith
sharedDate
sharedType
Run Code Online (Sandbox Code Playgroud)
这里,每列可以映射到相应的实体,但它们可以为空.sharedType可以识别哪个关系是"活动的".
所以,问题是,哪种做法最好,既有数据库方面也有hibernate映射(最终查询,性能方面).
谢谢M.相反
正如 TheStijn 所建议的那样,在研究了设置继承关系的不同方法后,我采用了“每个类层次结构单个表”的方法,最终得到的表如下:
SHARES
---------
id PK
shared_by FK to User
shared_with FK to User
shared_Date
document_id nullable FK to Document
post_id nullable FK to Posts
... more ids here to link to more entities
type_discriminator (values, DOCUMENT, POST ... )
Run Code Online (Sandbox Code Playgroud)
在 Hibernate/Java 方面,One Share 抽象类作为...
@Entity
@Table(name="SHARES")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE_DISCRIMINATOR", discriminatorType=DiscriminatorType.STRING)
public abstract class Share {
@Id
@Column( name="ID", nullable=false )
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
@ManyToOne
@JoinColumn( name="SHARED_BY", nullable=false )
private User sharedBy;
@ManyToOne
@JoinColumn( name="SHARED_WITH", nullable=false )
private User sharedWith;
@Column(name="SHARED_DATE", columnDefinition="TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
private Date sharedDate;
...
}
Run Code Online (Sandbox Code Playgroud)
还有两个普通班..
@Entity
@DiscriminatorValue("DOCUMENT")
public class SharedDocument extends Share {
@ManyToOne
@JoinColumn( name="DOCUMENT_ID", nullable=true )
private Document document;
....
}
@Entity
@DiscriminatorValue("POST")
public class SharedPost extends Share {
@ManyToOne
@JoinColumn( name="POST_ID", nullable=true )
private Post post;
....
}
Run Code Online (Sandbox Code Playgroud)
至于用法,仅将具体类用作:
@Test
public void saveNewDocumentShare(){
SharedDocument sharedDocument = new SharedDocument();
sharedDocument.setDocument(document1);
sharedDocument.setSharedBy(teacher1);
sharedDocument.setSharedWith(teacher2);
sharedDocument.setSharedDate(new Date());
sharedDocument.setCreatedBy("1");
sharedDocument.setCreatedDate(new Date());
sharedDocument.setModifiedBy("1");
sharedDocument.setModifiedDate(new Date());
SharedDocument savedSharedDocument = dao.saveSharedDocument(sharedDocument);
assertNotNull(savedSharedDocument);
assertThat(savedSharedDocument.getId(),notNullValue());
}
@Test
public void saveNewPostShare(){
SharedPost sharedWikiPage = new SharedWikiPage();
sharedPost.setPost(post1);
sharedPost.setSharedBy(teacher1);
sharedPost.setSharedWith(teacher2);
sharedPost.setSharedDate(new Date());
sharedPost.setCreatedBy("1");
sharedPost.setCreatedDate(new Date());
sharedPost.setModifiedBy("1");
sharedPost.setModifiedDate(new Date());
SharedPost savedSharedPost = dao.saveSharedPost(sharedPost);
assertNotNull(savedSharedPost);
assertThat(savedSharedPost.getId(),notNullValue());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7503 次 |
| 最近记录: |