我正在为项目使用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回答,一切都很好。但是在查询中使用“计数”或“总和”时,我在读取这些值时遇到了问题,而且我不知道如何读取它们。
答案 0 :(得分:2)
您不需要单独的路径。
除了一个简单的“ @Embedded”注释外,其他注释必须设置一个前缀:@Embedded(prefix =“ favorite_”)和@Embedded(prefix =“ bookmark _”)
< / li>在查询中,您选择的字段必须具有前缀。
代替
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();
请注意,查询中的别名列必须与复合数据类中定义的变量相同