我有两个问题都基于同一个房间关系问题,
第一个问题是更新组,我有很多句子(POJO)和很多组(POJO),组可以有很多句子,句子可以有很多组(M:N关系),它们之间用{{1 }}(POJO),
GroupsWithSentences
句子显示在public class GroupsWithSentences implements Visitable {
@Embedded
public Group group;
@Relation(
parentColumn = "groupId",
entity = Sentence.class,
entityColumn = "sentenceId",
associateBy = @Junction(value =
GroupIdsWithSentenceIdsJoin.class,
parentColumn = "groupId",
entityColumn = "sentenceId"
)
)
}
中。我可以在RecyclerView
中删除或移动(以后再移动)句子,然后当我高兴时保存该组,这是RecyclerView
的插入,但是当我保存该组语句时我已经从组中删除了,但我并没有将其删除,我可以理解为什么是这样并且可以手动修复它,但是删除句子和组之间的所有联接,然后再次插入它们减去被删除的联接似乎太过分了对于那些未被删除的(我不想从OnConflictStrategy.REPLACE
中删除连接表中的每个句子,因为我希望能够取消所做的任何更改),所以我的问题是,是否有更好的方法来更新会议室中的插入和删除关系?理想情况下,我想让我的RecyclerView
成为实体,如果更新它,那将更新我的联接表,但显然房间不喜欢这个。
我的另一个问题是关于排序的问题,有没有一种方法可以为关系提供一个GroupsWithSentences
参数用于其查询,我已经读到您不能,但是所有问题都不在第2版会议室中,目前保存订单列表并在查询后使用,否则订单总是不同的
出于代码简洁的目的,我可以根据要求添加任何内容
添加了组和句子模型,为简洁起见...
组模型
ORDER BY
句子模型
@Entity
public class Group {
@NotNull
@PrimaryKey()
@ColumnInfo(name = Constants.GROUP_ID, index = true)
private String groupId;
@ColumnInfo(name = Constants.GROUP_NAME)
private String groupName;
@ColumnInfo(name = Constants.SENTENCE_WORD_DESCRIPTION)
private String sentenceWordDescription;
@ColumnInfo(name = Constants.SENTENCE_WORD_TYPE)
private String sentenceWordType;
public Group() {
}
public String getSentenceWordDescription() {
return sentenceWordDescription;
}
public void setSentenceWordDescription(String sentenceWordDescription) {
this.sentenceWordDescription = sentenceWordDescription;
}
public String getSentenceWordType() {
return sentenceWordType;
}
public void setSentenceWordType(String sentenceWordType) {
this.sentenceWordType = sentenceWordType;
}
@Ignore
public Group(@NotNull String groupId, String groupName, String sentenceWordType, String sentenceWordDescription) {
this.groupId = groupId;
this.groupName = groupName;
this.sentenceWordType = sentenceWordType;
this.sentenceWordDescription = sentenceWordDescription;
}
@NotNull
public String getGroupId() {
return groupId;
}
public void setGroupId(@NotNull String groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
@Override
public String toString() {
return "Group{" +
"groupId='" + groupId + '\'' +
", groupName='" + groupName + '\'' +
", sentenceWordDescription='" + sentenceWordDescription + '\'' +
", sentenceWordType='" + sentenceWordType + '\'' +
'}';
}
}
加入模型
@Entity
public class Sentence implements Parcelable, Comparable<Sentence>, Visitable {
@NonNull
@PrimaryKey()
@ColumnInfo(name = Constants.SENTENCE_ID, index = true)
private String sentenceId;
@ColumnInfo(name = Constants.SENTENCES)
@TypeConverters({StringListConverter.class})
//If this is null we have a single word sentences
private List<String> sentences;
@ColumnInfo(name = Constants.TIME_STAMP)
private String createdDate;
@ColumnInfo(name = Constants.UPDATED_DATE)
private String lastUpdatedDate;
@ColumnInfo(name = Constants.SENTENCE_IMAGE_SMALL)
@TypeConverters({StringListConverter.class})
private List<String> smallImages;
@ColumnInfo(name = Constants.SENTENCE_IMAGE_LARGE)
@TypeConverters({StringListConverter.class})
private List<String> largeImages;
@ColumnInfo(name = Constants.SENTENCE_WORD_TYPE)
private String sentenceWordType;
@ColumnInfo(name = Constants.SENTENCE_IMAGE_TYPE)
private String sentenceImageType;
@ColumnInfo(name = Constants.SENTENCE_WORD_DESCRIPTION)
private String sentenceWordDescription;
@ColumnInfo(name = Constants.SENTENCE_WORD)
private String sentenceWords;
@ColumnInfo(name = Constants.SENTENCE_WORD_SOUND)
private String sentenceWordSound;
@ColumnInfo(name = Constants.SENTENCE_WORD_FAV)
private boolean isFavourite;
@ColumnInfo(name = Constants.SENTENCE_CLICKED)
private int clicks;
@ColumnInfo(name = Constants.SENTENCE_KEY_STAGE)
private int keyStage;
// TODO: change this to userEdited and add a firebase image url
@ColumnInfo(name = Constants.SENTENCE_USER_ADDED)
private boolean isUserAdded;
@ColumnInfo(name = Constants.SENTENCE_PREDICTIONS)
@TypeConverters({StringListConverter.class})
private List<String> predictions;
public Sentence() {
}
@Ignore
public Sentence(@NotNull String sentenceId, List<String> sentences, String createdDate,
String lastUpdatedDate, List<String> smallImages, List<String> largeImages,
String sentenceWordType,
String sentenceImageType, String sentenceWordDescription, String sentenceWords,
String sentenceWordSound, boolean isFavourite,
int clicks, int keyStage, boolean isUserAdded, List<String> predictions) {
this.sentenceId = sentenceId;
this.sentences = sentences;
this.createdDate = createdDate;
this.lastUpdatedDate = lastUpdatedDate;
this.smallImages = smallImages;
this.largeImages = largeImages;
this.sentenceWordType = sentenceWordType;
this.sentenceImageType = sentenceImageType;
this.sentenceWordDescription = sentenceWordDescription;
this.sentenceWords = sentenceWords;
this.sentenceWordSound = sentenceWordSound;
this.isFavourite = isFavourite;
this.clicks = clicks;
this.keyStage = keyStage;
this.isUserAdded = isUserAdded;
this.predictions = predictions;
}
@Ignore
public Sentence(Sentence thisSentence, Sentence otherSentence) {
this.sentenceId = thisSentence.getSentenceId();
this.createdDate = otherSentence.getCreatedDate();
this.sentences = otherSentence.sentences;
this.smallImages = thisSentence.getSmallImages();
this.largeImages = thisSentence.getLargeImages();
this.sentenceWordType = thisSentence.getSentenceWordType();
this.sentenceImageType = thisSentence.getSentenceWordType();
this.sentenceWordDescription = thisSentence.getSentenceWordDescription();
this.sentenceWords = thisSentence.getSentenceWords();
this.sentenceWordSound = thisSentence.getSentenceWordSound();
this.isFavourite = thisSentence.isFavourite();
this.clicks = thisSentence.getClicks();
this.keyStage = thisSentence.getKeyStage();
this.isUserAdded = thisSentence.isUserAdded();
this.predictions = thisSentence.getPredictions();
this.lastUpdatedDate = thisSentence.getLastUpdatedDate();
}
@Ignore
public Sentence(SentenceGroup sentence, List<Sentence> sentenceList) {
this.sentenceId = sentence.getSentenceId();
this.createdDate = sentence.getCreatedDate();
this.lastUpdatedDate = sentence.getLastUpdatedDate();
this.smallImages = sentence.getSmallImages();
this.largeImages = sentence.getLargeImages();
this.sentenceWordType = sentence.getSentenceWordType();
this.sentenceImageType = sentence.getSentenceImageType();
this.sentenceWordDescription = sentence.getSentenceWordDescription();
this.sentenceWords = sentence.getSentenceWords();
this.sentenceWordSound = sentence.getSentenceWordSound();
this.isFavourite = sentence.isFavourite();
this.clicks = sentence.getClicks();
this.keyStage = sentence.getKeyStage();
this.isUserAdded = sentence.isUserAdded();
this.predictions = sentence.getPredictions();
List<String> idList = new ArrayList<>();
if (sentenceList != null){
for (Sentence s : sentenceList){
idList.add(s.getSentenceId());
}
}
this.sentences = idList;
}
@Ignore
public Sentence(List<String> cardImageSmall, List<String> cardImageLarge,Sentence card) {
this.sentenceId = card.getSentenceId();
this.smallImages = cardImageSmall;
this.largeImages = cardImageLarge;
this.sentences = card.getSentences();
this.sentenceWordType = card.getSentenceWordType();
this.sentenceWordDescription = card.getSentenceWordDescription();
this.sentenceWords = card.getSentenceWords();
this.sentenceWordSound = card.getSentenceWordSound();
this.isFavourite = card.isFavourite();
this.clicks = card.getClicks();
this.keyStage = card.getKeyStage();
this.predictions = card.getPredictions();
this.isUserAdded = card.isUserAdded();
this.createdDate = card.getCreatedDate();
this.lastUpdatedDate = card.getLastUpdatedDate();
}
protected Sentence(Parcel in) {
sentenceId = Objects.requireNonNull(in.readString());
sentences = in.createStringArrayList();
createdDate = in.readString();
smallImages = in.createStringArrayList();
largeImages = in.createStringArrayList();
sentenceWordType = in.readString();
sentenceImageType = in.readString();
sentenceWordDescription = in.readString();
sentenceWords = in.readString();
sentenceWordSound = in.readString();
isFavourite = in.readByte() != 0;
clicks = in.readInt();
keyStage = in.readInt();
isUserAdded = in.readByte() != 0;
predictions = in.createStringArrayList();
lastUpdatedDate = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(sentenceId);
dest.writeStringList(sentences);
dest.writeString(createdDate);
dest.writeString(lastUpdatedDate);
dest.writeStringList(smallImages);
dest.writeStringList(largeImages);
dest.writeString(sentenceWordType);
dest.writeString(sentenceImageType);
dest.writeString(sentenceWordDescription);
dest.writeString(sentenceWords);
dest.writeString(sentenceWordSound);
dest.writeByte((byte) (isFavourite ? 1 : 0));
dest.writeInt(clicks);
dest.writeInt(keyStage);
dest.writeByte((byte) (isUserAdded ? 1 : 0));
dest.writeStringList(predictions);
}
public static Creator<Sentence> getCREATOR() {
return CREATOR;
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Sentence> CREATOR = new Creator<Sentence>() {
@Override
public Sentence createFromParcel(Parcel in) {
return new Sentence(in);
}
@Override
public Sentence[] newArray(int size) {
return new Sentence[size];
}
};
public String getSentenceId() {
return sentenceId;
}
public void setSentenceId(String sentenceId) {
this.sentenceId = sentenceId;
}
public List<String> getSentences() {
return sentences;
}
public void setSentences(List<String> sentences) {
this.sentences = sentences;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getLastUpdatedDate() {
return lastUpdatedDate;
}
public void setLastUpdatedDate(String lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
}
public List<String> getSmallImages() {
return smallImages;
}
public void setSmallImages(List<String> smallImages) {
this.smallImages = smallImages;
}
public List<String> getLargeImages() {
return largeImages;
}
public void setLargeImages(List<String> largeImages) {
this.largeImages = largeImages;
}
public String getSentenceWordType() {
return sentenceWordType;
}
public void setSentenceWordType(String sentenceWordType) {
this.sentenceWordType = sentenceWordType;
}
public String getSentenceWordDescription() {
return sentenceWordDescription;
}
public void setSentenceWordDescription(String sentenceWordDescription) {
this.sentenceWordDescription = sentenceWordDescription;
}
public String getSentenceWords() {
return sentenceWords;
}
public void setSentenceWords(String sentenceWords) {
this.sentenceWords = sentenceWords;
}
public String getSentenceWordSound() {
return sentenceWordSound;
}
public void setSentenceWordSound(String sentenceWordSound) {
this.sentenceWordSound = sentenceWordSound;
}
public boolean isFavourite() {
return isFavourite;
}
public void setFavourite(boolean isFavourite) {
this.isFavourite = isFavourite;
}
public int getClicks() {
return clicks;
}
public void setClicks(int clicks) {
this.clicks = clicks;
}
public int getKeyStage() {
return keyStage;
}
public void setKeyStage(int keyStage) {
this.keyStage = keyStage;
}
public boolean isUserAdded() {
return isUserAdded;
}
public void setUserAdded(boolean isUserAdded) {
this.isUserAdded = isUserAdded;
}
public List<String> getPredictions() {
return predictions;
}
public void setPredictions(List<String> predictions) {
this.predictions = predictions;
}
public String getSentenceImageType() {
return sentenceImageType;
}
public void setSentenceImageType(String sentenceImageType) {
this.sentenceImageType = sentenceImageType;
}
@Override
public int compareTo(Sentence o) {
Date date = DateStringConverter.getDateFromString(this.getSentenceId());
Date date2 = DateStringConverter.getDateFromString(o.getSentenceId());
Log.d("PreviousSentence", "return " + date.compareTo(date2));
return date.compareTo(date2);
}
@Override
public String toString() {
return "Sentence{" +
"sentenceId='" + sentenceId + '\'' +
", sentences=" + sentences +
", createdDate='" + createdDate + '\'' +
", lastUpdatedDate='" + lastUpdatedDate + '\'' +
", smallImages=" + smallImages +
", largeImages=" + largeImages +
", sentenceWordType='" + sentenceWordType + '\'' +
", sentenceImageType='" + sentenceImageType + '\'' +
", sentenceWordDescription='" + sentenceWordDescription + '\'' +
", sentenceWords='" + sentenceWords + '\'' +
", sentenceWordSound='" + sentenceWordSound + '\'' +
", isFavourite=" + isFavourite +
", clicks=" + clicks +
", keyStage=" + keyStage +
", isUserAdded=" + isUserAdded +
", predictions=" + predictions +
'}';
}
@Override
public int type(TypeFactory typeFactory) {
return typeFactory.type(this);
}
@Override
public String id() {
return sentenceId;
}
}
答案 0 :(得分:2)
您应根据此official guide,在您的加入模型和其他两个模型之间定义外键关系。
然后,您可以在外键定义中指定更新和删除策略,在您的情况下应为CASCADE
加入模型的实体注释应该是这样的
@Entity(primaryKeys = {"groupId", "sentenceId"},
foreignKeys = {
@ForeignKey(entity = Group.class,
parentColumns = "id",
childColumns = "groupId",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE),
@ForeignKey(entity = Sentence.class,
parentColumns = "id",
childColumns = "sentenceId",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE)
})
要进行排序,您应该在Dao中编写查询。根据此doc
,您不能在@Relation
中使用@Entity
请注意,@ Relation批注只能在POJO类中使用,而Entity类不能具有关系。这是一项设计决策,以避免在实体设置中出现常见的陷阱。您可以在Room主文档中阅读有关此内容的更多信息。加载数据时,您可以通过创建扩展实体的POJO类来解决此限制。