如何获得与 greenDao 的递归 many-to-many 关系
How to get a recursive many-to-many relation with greenDao
我想获得类别的递归数据结构。
OOM结构:
一个类别应该管理一个列表或一组(子)类别。
ROM结构:
ROM的物理结构:
category (_id_, title)
overAndSubCategories (ocId, scId)
overAndSubCategories
的两个属性都是外键,引用category
的id。
category的标题是唯一的,可以是主键,但是greenDao目前还不支持字符串作为主键。所以我按照记录添加了一个 id。
GreenDao 不支持多对多关系。我能否实施解决此结构问题的等效方案?
*两张图片均由 yEd
提供支持
我不确定这个解决方案是正确的还是最好的,因为我不是 100% 知道我在做什么,但它确实有效。
方案生成器:
final Entity category = schema.addEntity("Category");
category.addIdProperty();
category.addStringProperty("Name").notNull().unique().index();
final Entity overSubCategory = schema.addEntity("OverSubCategory");
// no own id! we do not want to load objects of this type
final Property fkOverCategory = overSubCategory.addLongProperty("IdO").notNull().getProperty();
final Property fkSubCategory = overSubCategory.addLongProperty("IdS").notNull().getProperty();
overSubCategory.addToOne(category, fkOverCategory, "OverCategory");
overSubCategory.addToOne(category, fkSubCategory, "SubCategory");
这个方案的用法:
/* # write # */
final CategoryDao categoryDao = session.getCategoryDao();
final OverSubCategoryDao overSubCategory = session.getOverSubCategoryDao();
// overcategories
final Category oC1 = new Category(1l, "food and drink");
final Category oC2 = new Category(2l, "party");
// subcategories
final Category sC1 = new Category(3l, "junkfood");
final Category sC2 = new Category(4l, "restaurante");
final Category sC3 = new Category(5l, "pub");
categoryDao.insert(oC1);
categoryDao.insert(oC2);
categoryDao.insert(sC1);
categoryDao.insert(sC2);
categoryDao.insert(sC3);
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC1.getId()) );
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC2.getId()) );
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC3.getId()) );
overSubCategory.insert( new OverSubCategory(oC2.getId(), sC3.getId()) );
/* # read # */
final QueryBuilder<Category> cqb = categoryDao.queryBuilder();
// all categories that are subcategories and ...
final Join joinOverSubCategories = cqb.join(OverSubCategory.class, OverSubCategoryDao.Properties.IdS);
// ... whose overcategories ...
final Join joinSubCategories = cqb.join(joinOverSubCategories, OverSubCategoryDao.Properties.IdO, Category.class, CategoryDao.Properties.Id);
// ... named "food and drink".
joinSubCategories.where(CategoryDao.Properties.Name.eq("food and drink"));
final List<Category> someSubcategories = cqb.list();
两个连接加上一个 where 条件似乎有点过分了。
需要更好的解决方案。
我想获得类别的递归数据结构。
OOM结构:
一个类别应该管理一个列表或一组(子)类别。
ROM结构:
ROM的物理结构:
category (_id_, title)
overAndSubCategories (ocId, scId)
overAndSubCategories
的两个属性都是外键,引用category
的id。
category的标题是唯一的,可以是主键,但是greenDao目前还不支持字符串作为主键。所以我按照记录添加了一个 id。
GreenDao 不支持多对多关系。我能否实施解决此结构问题的等效方案?
*两张图片均由 yEd
提供支持我不确定这个解决方案是正确的还是最好的,因为我不是 100% 知道我在做什么,但它确实有效。
方案生成器:
final Entity category = schema.addEntity("Category");
category.addIdProperty();
category.addStringProperty("Name").notNull().unique().index();
final Entity overSubCategory = schema.addEntity("OverSubCategory");
// no own id! we do not want to load objects of this type
final Property fkOverCategory = overSubCategory.addLongProperty("IdO").notNull().getProperty();
final Property fkSubCategory = overSubCategory.addLongProperty("IdS").notNull().getProperty();
overSubCategory.addToOne(category, fkOverCategory, "OverCategory");
overSubCategory.addToOne(category, fkSubCategory, "SubCategory");
这个方案的用法:
/* # write # */
final CategoryDao categoryDao = session.getCategoryDao();
final OverSubCategoryDao overSubCategory = session.getOverSubCategoryDao();
// overcategories
final Category oC1 = new Category(1l, "food and drink");
final Category oC2 = new Category(2l, "party");
// subcategories
final Category sC1 = new Category(3l, "junkfood");
final Category sC2 = new Category(4l, "restaurante");
final Category sC3 = new Category(5l, "pub");
categoryDao.insert(oC1);
categoryDao.insert(oC2);
categoryDao.insert(sC1);
categoryDao.insert(sC2);
categoryDao.insert(sC3);
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC1.getId()) );
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC2.getId()) );
overSubCategory.insert( new OverSubCategory(oC1.getId(), sC3.getId()) );
overSubCategory.insert( new OverSubCategory(oC2.getId(), sC3.getId()) );
/* # read # */
final QueryBuilder<Category> cqb = categoryDao.queryBuilder();
// all categories that are subcategories and ...
final Join joinOverSubCategories = cqb.join(OverSubCategory.class, OverSubCategoryDao.Properties.IdS);
// ... whose overcategories ...
final Join joinSubCategories = cqb.join(joinOverSubCategories, OverSubCategoryDao.Properties.IdO, Category.class, CategoryDao.Properties.Id);
// ... named "food and drink".
joinSubCategories.where(CategoryDao.Properties.Name.eq("food and drink"));
final List<Category> someSubcategories = cqb.list();
两个连接加上一个 where 条件似乎有点过分了。 需要更好的解决方案。