我正在尝试使用MongoDB来存储一系列文档。这些文档共享一些标准属性,同时具有多种变体。我们使用继承来实现 POJO。基类是文档,而它有几个子类,如发票和订单,与文档类相比,它有几个附加字段。
class Document {
DocTypeEnum type;
String title;
}
class Invoice extends Document{
Date dueDate;
}
class Order extends Document{
List<LineItems> items;
}
是否有ORM框架支持查询集合并根据其类型字段返回混合对象(发票,订单,基本文档等)的列表?
List<Document> results = DocCollection.find(...);
多谢!
Morhia支持多态性,即使不需要类型枚举或任何东西。它存储实际的实例类名以及其余的数据。查看@Polymorphic注释。
您可以使用任何支持所需数据库方言的ORM。休眠框架具有执行此操作的对象/网格映射器(OGM)子项目。
BuguMongo?http://code.google.com/p/bugumongo
另一种选择是使用 Jongo,它将多态处理委托给 Jackson。我写了一篇包含一些示例的博客文章,您可以在 GitHub 上找到完整的代码库。
在你的特定方案中,Jackson 的解决方案将如下所示:
public enum DocTypeEnum {
INVOICE(Constants.INVOICE), ORDER(Constants.ORDER);
DocTypeEnum(String docTypeString) {
}
public static class Constants {
public static final String INVOICE = "INVOICE";
public static final String ORDER = "ORDER";
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY,
property = Document.TYPE)
@JsonSubTypes({
@JsonSubTypes.Type(value = Invoice.class, name = DocTypeEnum.Constants.INVOICE),
@JsonSubTypes.Type(value = Order.class, name = DocTypeEnum.Constants.ORDER)
})
public class Document {
public static final String TYPE = "type";
public static final String TITLE = "title";
private final DocTypeEnum type;
private final String title;
public Document(DocTypeEnum type, String title) {
this.type = type;
this.title = title;
}
@JsonProperty(TYPE)
public DocTypeEnum getType() {
return type;
}
@JsonProperty(TITLE)
public String getTitle() {
return title;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Invoice extends Document {
public static final String DUE_DATE = "due_date";
private final Date dueDate;
public Invoice(String title, Date dueDate) {
super(DocTypeEnum.INVOICE, title);
this.dueDate = dueDate;
}
@JsonProperty(DUE_DATE)
public Date getDueDate() {
return dueDate;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Order extends Document {
public static final String ITEMS = "items";
private final List<LineItems> items;
public Order(String title, List<LineItems> items) {
super(DocTypeEnum.ORDER, title);
this.items = items;
}
@JsonProperty(ITEMS)
public List<LineItems> getItems() {
return items;
}
}