我找不到任何关于在Google App Engine上使用Objectify在对象之间建立多对多关系的适当方法的文档。
任何人都可以解释如何做到这一点?我需要为此创建一个新的“加入”类吗?效率如何?
答案 0 :(得分:2)
您需要支持哪些类型的查询?
最简单的解决方案是:
@Entity
public class StoredObject {
@Id
private Long id;
private List<Long> relatedIds;
}
然后,给定StoredObject
,您可以致电objectify.get(StoredObject.class, storedObject.getRelatedIds())
来获取所有相关的ID。
为了加快我自己的应用程序中的一些查询,我确实创建了一些连接类。费用来自写入时间(您必须维护连接)但是读取时间是连续结果的单个索引扫描!
答案 1 :(得分:2)
这不是在Objectify中映射多对多关系的最佳方法。最好的方法是创建一个映射关系的实体。例如,假设您有两个对象A和B,并且它们以某种方式关联。你可以创建一个类似于:
的类Class Link{
Key<?> master;
key<?> slave;
public Link(){
}
public setLink(Entity master, Entity slave){
//initialize
}
}
然后,您可以创建一个链接实体来建模关系。这会自动映射一对一或多对多关系
答案 2 :(得分:2)
我已经用Objectify 4.0解决了这种方法:
@Entity
@Index
public class Module {
@Id
private Long id;
private String name;
@Load
private List<Ref<Template>> templates;
public List<Template> getTemplates() {
List<Template> templates = new ArrayList<Template>();
for (Ref<Template> temp : this.templates) {
templates.add(temp.get());
}
return templates;
}
public void setTemplates(List<Template> templatesParm) {
List<Ref<Template>> templates = new ArrayList<Ref<Template>>();
for (Template temp : templatesParm) {
templates.add(Ref.create(temp));
}
this.templates = templates;
}
答案 3 :(得分:1)
让我们暂时考虑一个人;如果你想让一个对象A“有很多”对象B-s,那么只有两种方法可以做到:
关系方式:将每个B点设置为A.当你有A0并想要所有与之相关的B时,只需查询指向给定A0的Bs。
< / LI>NoSQL / ObjectStore方式:make A有一个字段,其中包含指向B-s的指针(键)列表。请注意,这种方式也允许B-s按特定顺序排列(尽管GAE / Java文档恰恰相反。)
哪一个最好取决于。 ObjectStore方式受对象大小的限制。关系方式存在一个微妙的问题,除非A和所有B在同一个实体组中,并且您在事务中执行祖先查询(或者即使它不在事务中),您也可以保证获得所有的B指向A。但是,如果A和B跨越实体组,则可能(尽管可能不太可能)您将获得不满足查询谓词的B,或者错过了一个B:https://developers.google.com/appengine/articles/transaction_isolation
在(现在标准的)High Replication数据存储区中,该事务 通常在几百毫秒内完全应用 提交返回后。但是,即使它不完全 应用,后续读取,写入和祖先查询将始终 反映提交的结果,因为这些操作适用于任何 执行前的未完成修改。但是,跨越的查询 多个实体组无法确定是否有任何 执行前的未完成修改,可能会返回陈旧或 部分应用的结果。
现在为许多人:我曾经读过一个故事,描述了在太空中上厕所;有四种组合:太空船的内部/外部和两种上厕所。对于在船外(航天服)和消除实体的最后组合,唯一的答案是“没有优雅的方式”(也是文章的标题):http://settlement.arc.nasa.gov/CoEvolutionBook/SPACE.HTML#There不是否优雅的方式 ......这也是GAE中许多关系的答案。您可以使用连接类构建它们,并且可以使用查询或键列表来实现连接的每一面。