在 ROOM 中连接表时,表中的字段同名问题
The field's same name issue in the tables, when join tables in ROOM
我正在为我的项目使用 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”(如下所示)。
为了修复相同的字段问题,我使用 prefix 作为 Thomas Fischer response
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();
}
但是,在使用查询之后,我再次遇到以下代码的错误(Activity 或 Fragment):
mWordAndFavoriteAndBookmark.getFavorite().getTime();
我认为这是由于使用了Perfix,但我不知道这个问题的解决方法
编辑: 通过回答,一切都很好。但是当在我的查询中使用 "Count" 或 "Sum" 时,我无法读取这些值并且我不知道如何读取它们。
您不需要单独的 dao。
除了一个普通的“@Embedded”注解,其他注解都必须设置前缀:@Embedded(prefix = "favorite_") 和@Embedded(prefix = "bookmark_")
在您的查询中,您选择的字段必须有前缀。
而不是
select * from word join bookmark join favorite // pseudo code
您必须将字段别名为您的前缀:
select word.*, bookmark.id as bookmark_id..., favorite.id as favorite_id... from...
这可以防止三个 id 列在查询中相互覆盖。有了前缀,dao 将期望 table 的所有列在实际列名前面都有该前缀。
还有你得到的确切错误是什么?
我猜可能会有 NPE。这可能与您的查询有关。因此,如果您也可以包括查询,将有助于找到问题。
为了解决"Count"或"Sum"字段问题,我使用了新的复合数据class。
如下:
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 class 中,我引用了这个字段:
@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();
注意查询中的别名列必须与复合数据中定义的变量相同class
我正在为我的项目使用 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”(如下所示)。 为了修复相同的字段问题,我使用 prefix 作为 Thomas Fischer response
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();
}
但是,在使用查询之后,我再次遇到以下代码的错误(Activity 或 Fragment):
mWordAndFavoriteAndBookmark.getFavorite().getTime();
我认为这是由于使用了Perfix,但我不知道这个问题的解决方法
编辑: 通过
您不需要单独的 dao。
除了一个普通的“@Embedded”注解,其他注解都必须设置前缀:@Embedded(prefix = "favorite_") 和@Embedded(prefix = "bookmark_")
在您的查询中,您选择的字段必须有前缀。
而不是
select * from word join bookmark join favorite // pseudo code
您必须将字段别名为您的前缀:
select word.*, bookmark.id as bookmark_id..., favorite.id as favorite_id... from...
这可以防止三个 id 列在查询中相互覆盖。有了前缀,dao 将期望 table 的所有列在实际列名前面都有该前缀。
还有你得到的确切错误是什么?
我猜可能会有 NPE。这可能与您的查询有关。因此,如果您也可以包括查询,将有助于找到问题。
为了解决"Count"或"Sum"字段问题,我使用了新的复合数据class。 如下:
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 class 中,我引用了这个字段:
@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();
注意查询中的别名列必须与复合数据中定义的变量相同class