在ROOM中联接表时,表中的字段名称相同

时间:2018-07-25 06:53:40

标签: android database android-room jointable

我正在为项目使用ROOM。但是我很难在表之间进行联接,因为表具有相同的名称字段。

例如,我的项目有树表“ word”和“ favorite”和“ bookmark”,它们具有相同的名称字段。

1个字

@Entity(tableName = "word")
public class Word {

    @NonNull
    @PrimaryKey(autoGenerate = true)
    private int id;

    @NonNull
    private String title;
    private String mean;
    private String pronunciation;

    // Getter and Setter
}

2-最爱

@Entity(tableName = "favorite",
    foreignKeys = @ForeignKey(
            entity = Word.class,
            parentColumns = "id",
            childColumns = "word_id",
            onDelete = CASCADE,
            onUpdate = CASCADE))
public class Favorite {

    @NonNull
    @PrimaryKey
    private int word_id;
    private long time;

    // Getter and Setter
}

3-书签

     @Entity(tableName = "bookmark",
         primaryKeys = {"word_id", "category_id"},
         foreignKeys = {
            @ForeignKey(entity = Word.class,
                    parentColumns = "id",
                    childColumns = "word_id",
                    onDelete = CASCADE,
                    onUpdate = CASCADE)})
     public class Bookmark {
         @NonNull
         private int word_id;
         private long time;
         private int color;

        // Getter and Setter
}

要在这三个之间创建连接,我定义了一个新类型,称为“ WordAndFavoriteAndBookmark”,并使用了“ @Embedded”(如下所示)。 为了解决同一个字段问题,我使用前缀作为Thomas Fischer响应

4- WordAndFavoriteAndBookmark

   public class WordAndFavoriteAndBookmark {
    @Embedded
    private Word word;

    @Embedded(prefix = "favorite_")
    private Favorite favorite;

    @Embedded(prefix = "bookmark_")
    private Bookmark bookmark;

    //Getter and Setter
    public Word getWord() { return word; }
    public void setWord(Word word) {this.word = word;}    
    public Favorite getFavorite() { return favorite; }    
    public void setFavorite(Favorite favorite) { this.favorite = favorite;}    
    public Bookmark getBookmark() { return bookmark;  }    
    public void setBookmark(Bookmark bookmark) { this.bookmark = bookmark; }    
    }

要在这些表之间创建联接,我定义了一个新的 @Dao

 @Dao
public interface WordAndFavoriteAndBookmarkDao {
    @Query("SELECT word.*, favorite.time FROM word LEFT JOIN favorite " +
            "ON word.id = favorite.word_id")
    LiveData<List<WordAndFavoriteAndBookmark>> getAllWordsByFavoritesForLanguage();
    }

但是,再次使用查询后,在我的视图(活动性或片段)中遇到了以下代码的错误:

mWordAndFavoriteAndBookmark.getFavorite().getTime();

我认为这是由于使用了 Perfix ,但我不知道解决该问题的方法

已编辑: Thomas Fisher回答,一切都很好。但是在查询中使用“计数”或“总和”时,我在读取这些值时遇到了问题,而且我不知道如何读取它们。

2 个答案:

答案 0 :(得分:2)

  1. 您不需要单独的路径。

  2. 除了一个简单的“ @Embedded”注释外,其他注释必须设置一个前缀:@Embedded(prefix =“ favorite_”)和@Embedded(prefix =“ bookmark _”)

    < / li>
  3. 在查询中,您选择的字段必须具有前缀。

代替

select * from word join bookmark join favorite // pseudo code

您必须为字段加上别名作为前缀:

select word.*, bookmark.id as bookmark_id..., favorite.id as favorite_id... from...

这可防止三个id列在查询中相互覆盖。有了前缀,Dao会期望该表的所有列在实际列名的前面都具有该前缀。

您还会得到什么确切的错误?

我猜可能会有NPE。这可能与您的查询有关。因此,如果您还可以包括该查询,则将有助于发现问题。

答案 1 :(得分:0)

为解决“计数”或“和”字段问题,我使用了新的复合数据类。 如下:

public static class CategoryAndEssentials {
    @Embedded
    private BookmarkCategory bookmarkCategory;

    private int wordCount;

    public BookmarkCategory getBookmarkCategory() { return bookmarkCategory; }
    public void setBookmarkCategory(BookmarkCategory bookmarkCategory) { this.bookmarkCategory = bookmarkCategory;}
    public int getWordCount() { return wordCount; }
    public void setWordCount(int wordCount) { this.wordCount = wordCount; }
}

在查询定义的Dao类中,我引用了此字段:

@Query("SELECT " +
            "bookmarkCategory.*, " +
            "COUNT(bookmark.category_id) AS wordCount, " +
        "FROM bookmarkCategory LEFT JOIN bookmark " +
        "ON bookmarkCategory.id = bookmark.category_id " +
        "GROUP BY bookmarkCategory.id ")
LiveData<List<EntityClassForJoinTables.CategoryAndEssentials>> getAllCategoriesAndEssentials();

请注意,查询中的别名列必须与复合数据类中定义的变量相同