更新:感谢 funql/Kim。我理解您的意思-因此,如果您允许我提出一个后续问题,实际上是否有一种方法可以使用 Couch 进行对象持久性(如 Funql for Mongo 所建议的那样)?据我在开始这个项目之前的理解,这是 NoSQL DB 的好处之一——你不需要担心 DAO 层,你几乎可以将一个对象转储到一个 Document 中并根据需要将其拉出,不麻烦,让您的类定义完全暗示架构定义,我看不出它可以在 MongoDB 但在 CouchDB 中工作的根本原因?
我是第一次在企业应用程序中使用 CouchDB,感觉就像我错过了关于 NoSQL 思维方式的一些基本知识。
假设您有以下 Java 类:
public class Customer { ... }
public abstract class Product { ... } // could just as well be an interface
public class ProductA extends Product { ... };
public class ProductB extends Product { ... };
public class Sale {
private String transactionId;
private Customer customer;
private List<Product> items;
// ...
}
将销售存储到 Couch 数据库(或其他文档存储数据库)时,我最终得到一个包含整个销售的单个文档,这就是我想要的。但是,当我开始尝试存储/检索抽象类或实现接口的类时,我遇到了一个问题。我的销售记录通常看起来像这样(简化):
{
"transactionId": "12345",
"customer": { "name": "Joe Soap" },
"items": [
{
"name": "Coke",
"price": 12.99,
"qty": 1
},
{
"name": "Minced meat",
"weight": 1.23,
"price": 49.99
}
]
}
现在,对于客户而言,检索该数据很简单——我可以使用自定义序列化器/反序列化器并使用反射来判断它Sale.customer
是一个实例Customer
,实例化一个实例,并从 JSON 数据中设置其字段。
但是,这对于记录变得更加棘手items
,因为我不知道Product
要为列表中的每个元素实例化哪个子类(而且我无法初始化抽象类或接口的实例)。
我试图通过将完整的类名与数据一起存储来解决这个问题(例如,每条Product
记录将包含一个附加@class
字段来指示什么类型的对象被序列化,因此在反序列化时应该初始化什么类型)但这意味着我例如,如果我将该类移动到不同的包(因为存储的@class
值将是无效的),那么我会为自己制造一个问题。虽然这可以通过迁移脚本(或其他方法)来缓解,但感觉好像我错过了一个基本点并且正在围绕它进行攻击。
有人可以告诉我我做错了什么吗?是否有更优雅的方法可以让我不必过多地摆弄序列化代码,因为我的理解是 NoSQL 数据库应该减少开发人员编写持久性代码所需的时间?
对于它的价值,我尝试过使用 Ektorp 和 LightCouch,并且两者都有类似的问题。