android - 房间关系插入删除更新排序
问题描述
我有两个问题都基于相同的房间关系问题,
第一个问题是更新组,我有很多句子(POJO)和很多组(POJO),组可以有很多句子,句子可以有很多组(M:N 关系),它们由一个GroupsWithSentences
(POJO)关联,
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"
)
)
}
句子显示在 a 中RecyclerView
。我可以删除或移动(稍后再移动)句子,RecyclerView
然后当我很高兴我保存组时,这是一个插入OnConflictStrategy.REPLACE
,但是当我保存组时,我删除的句子不会从组,我可以看到为什么会这样并且可以手动修复它,但是删除句子和组之间的所有连接然后再将它们全部插入减去那些被删除的连接似乎有点过分,尤其是那些没有被删除的连接(我不想删除连接表中的每个句子,RecyclerView
因为我希望能够取消所做的任何更改)所以我的问题是,有没有更好的方法来更新房间中的插入和删除关系?理想情况下,我只想拥有我的GroupsWithSentences
成为一个实体,如果我更新它,那将更新我的连接表,但显然房间不喜欢这样。
我的另一个问题是订购,有没有办法为关系提供一个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;
}
}
加盟模式
@Entity(primaryKeys = {"groupId", "sentenceId"})
public class GroupIdsWithSentenceIdsJoin {
@NotNull
@ColumnInfo(name = "groupId", index = true)
private String groupId;
@NotNull
@ColumnInfo(name = "sentenceId", index = true)
private String sentenceId;
@Ignore
public GroupIdsWithSentenceIdsJoin(@NotNull String groupId, @NotNull String sentenceId) {
this.groupId = groupId;
this.sentenceId = sentenceId;
}
public GroupIdsWithSentenceIdsJoin() {
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getSentenceId() {
return sentenceId;
}
public void setSentenceId(String sentenceId) {
this.sentenceId = sentenceId;
}
}
解决方案
您应该根据本官方指南定义您的加入模型和其他两个模型之间的外键关系。
然后,您可以在外键定义中指定更新和删除策略,在您的情况下应该是CASCADE
您的Join Model的实体注释应该是这样的
@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 中编写查询。根据此文档,您不能@Relation
在其中使用@Entity
注意@Relation 注解只能在 POJO 类中使用,Entity 类不能有关系。这是避免实体设置中常见陷阱的设计决策。您可以在 Room 主文档中了解更多相关信息。加载数据时,您可以通过创建扩展实体的 POJO 类来解决此限制。
推荐阅读
- php - 第一次使用 PHP SOAP 客户端
- wordpress - 带有通配符选项的 htaccess 将 htm 或 html 扩展名移回站点
- regex - 我将如何构造一个验证百分比的正则表达式?
- jquery - JQuery:使用setInterval每隔随机数秒显示文本
- python - 尝试创建用户名和密码以登录下一个 tkinter 窗口。如果用户并通过正确的登录按钮进入下一个屏幕
- c++ - 由于 Tree 类中的模板而出现错误
- php - 浏览器中的 PHP 错误未显示(使用 Docker)
- python - 如何从 save_formset 访问 Django 模型字段
- windows - 如何打印特定元素
- python-3.x - 如何调试此堆栈跟踪?(google.auth.transport.grpc.AuthMetadataPlugin)