ORMLite中相同类型的多个ForeignCollection

时间:2014-05-07 01:18:14

标签: android sqlite ormlite

我在Android上使用OrmLite获取与以下内容类似的结构:

Book类包含一个主BookArticle和一个辅助BookArticle的集合:

    @DatabaseTable(tableName = "BookV1", daoClass = BookDaoImplV1.class)
public class Book implements IBook {

    @DatabaseField(id = true)
    private String id;

    @ForeignCollectionField(eager = false)
    private ForeignCollection<BookArticle> primaryArticles;

    @ForeignCollectionField(eager = false)
    private ForeignCollection<BookArticle> secondaryArticles;

    // constructor getters setters etc...

}

然后BookArticle声明如下:

    @DatabaseTable(tableName = "BookArticleV1", daoClass = BookArticleDaoImplV1.class)
public class BookArticle implements IBookArticle {

    @DatabaseField(id = true)
    private String id;

    @DatabaseField
    private String title;

    @DatabaseField
    private String summary;

    // for ORM mapping only
    @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = BOOK_FIELDNAME, index = true)
    private Book book;

    // constructor getters setters etc..

}

现在用DAO保存BookArticles和Book工作正常但是当我想从数据库中获取我的Book实体并访问主要或辅助文章时(刷新()之后)我遇到了问题,因为两个集合都包含所有文章(小学和中学都有书的内容在他们的书中#39;列。

显然,当从DB中提取时,我需要将这些主要和次要文章分开。

我原本期望&#34; foreignFieldName&#34;成为我问题的答案。

@ForeignCollectionField(eager = false, foreignFieldName = "secondaryArticles")
private ForeignCollection<BookArticle> secondaryArticles;

但显然这种方式不起作用。

我有办法区分这两个系列吗? 也许使用简单的注释参数,例如&#34; owningFieldName&#34;或者与BookArticle数据一起保存在DB中的类似内容?

非常感谢你的帮助。

亚历

3 个答案:

答案 0 :(得分:3)

我遇到了同样的问题。

不是一个真正的解决方案,但你可以尝试只使用一个带有布尔值的列表来切换主要/次要文章,如下所示:

@DatabaseTable(tableName = "BookV1", daoClass = BookDaoImplV1.class)
public class Book implements IBook {

    @DatabaseField(id = true)
    private String id;

    @ForeignCollectionField(eager = false)
    private ForeignCollection<BookArticle> articles;

    // constructor getters setters etc...

}

然后是BookArticle类

@DatabaseTable(tableName = "BookArticleV1", daoClass = BookArticleDaoImplV1.class)
public class BookArticle implements IBookArticle {

    @DatabaseField(id = true)
    private String id;

    @DatabaseField
    private String title;

    @DatabaseField
    private String summary;

    @DatabaseField
    private boolean isSecondary;

    // for ORM mapping only
    @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = BOOK_FIELDNAME, index = true)
    private Book book;

    // constructor getters setters etc..

}

希望看到真正的答案

答案 1 :(得分:1)

如果要将相同类型的多个ForeignerCollections添加到一个类,则必须在BookArticle类中为ORM-Mapping添加2个字段,并将Book类中的此字段链接到ORM-Mapping字段。

例如

预订

@ForeignCollectionField(eager = false, foreignFieldName = "primaryBook")
private ForeignCollection<BookArticle> primaryArticles;

@ForeignCollectionField(eager = false, foreignFieldName = "secondaryBook")
private ForeignCollection<BookArticle> secondaryArticles;

BookArticle class

// for ORM mapping primary Books
@DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = BOOK_FIELDNAME, index = true)
private Book primaryBook;

// for ORM mapping secondary Books
@DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = BOOK_FIELDNAME, index = true)
private Book secondaryBook;

当您现在调用bookDao.queryAll()并访问辅助文章列表时,您将看到文章已正确链接。

缺点是,BookArticle表中有2个用于外国人密钥的字符。

问候语, Codenix

答案 2 :(得分:0)

来自官方文件Annotation Type ForeignCollectionField

  

标识类中的ForeignCollection字段的注释,该字段对应于外部表中与当前类的外部标识匹配的对象。

返回您的Book

代码
@ForeignCollectionField(eager = false)
private ForeignCollection<BookArticle> primaryArticles;

@ForeignCollectionField(eager = false)
private ForeignCollection<BookArticle> secondaryArticles;

刷新集合时,ormlite只进行简单查询

SELECT * FROM article WHERE book_id = 'id of book'

并将结果转换为BookArticle集合

如果你仍想在书和文章之间建立一对一的关系。接下来是最简单的实现初始要求的方法:

预订

    @DatabaseTable(tableName = "BookV1", daoClass = BookDaoImplV1.class)
public class Book implements IBook {

    @DatabaseField(id = true)
    private String id;

    @ForeignCollectionField(eager = false)
    private ForeignCollection<BookArticle> articles;

    public Collection<BookArticle> getArticles(boolean primary) throws SQLException {
        articles.refreshCollection();
        Collection<BookArticle> result = new ArrayList<BookArticle>();
        for (BookArticle article : articles) {
            if (article.isPrimary() == primary) result.add(article)
        }
        return result;
    }
}

BookArticle class

@DatabaseTable(tableName = "BookArticleV1", daoClass = BookArticleDaoImplV1.class)
public class BookArticle implements IBookArticle {

    private static final String BOOK_FIELDNAME = "book_id";
    @DatabaseField(id = true)
    private String id;

    @DatabaseField
    private String title;

    @DatabaseField
    private String summary;

    @DatabaseField
    private boolean primary;

    public boolean isPrimary() {
        return primary;
    }

    // for ORM mapping only
    @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = BOOK_FIELDNAME, index = true)
    private Book book;

    // constructor getters setters etc..

}

要做主要的文章你需要:

  • 将其链接到预订;
  • 将主要属性设置为true;
  • 更新DAO;

获取本书的主要文章:

  • 致电所需图书实体的getArticles(true);

对于用例“辅助”,请使用false值的相同步骤。