android - 具有空值的实体的房间(SQLite)替换策略不起作用
问题描述
我有实体类Person
,表中不应该有超过一个人具有相同的name
和feature
。但是,如果我将人名或功能设置为 null,则它不起作用。我怎样才能使它与空值一起工作?请参阅下面的代码。
测试
Context context = InstrumentationRegistry.getContext();
AppDb db = Room.inMemoryDatabaseBuilder(context, AppDb.class).allowMainThreadQueries().build();
PersonDao dao = db.personDao();
// replacement works here
dao.insert(new Person("Musk", "Alien"));
dao.insert(new Person("Musk", "Alien"));
// replacement doesn't work here
dao.insert(new Person("Trump", null));
dao.insert(new Person("Trump", null));
// fails - actual size = 3 (Musk, Trump, Trump)
assertEquals(2, dao.getAll().size());
人.java
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.PrimaryKey;
@Entity(tableName = "person", indices = {@Index(value = {"name", "feature"}, unique = true)})
public class Person {
@ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) private int id;
@ColumnInfo(name = "name") private String name;
@ColumnInfo(name = "feature") private String feature;
public Person(String name, String feature) {
this.name = name;
this.feature = feature;
}
public void setId(int id) { this.id = id; }
public int getId() { return id; }
public String getName() { return name; }
public String getFeature() { return feature; }
}
PersonDao.java
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import java.util.List;
@Dao
public interface PersonDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Person person);
@Query("SELECT * FROM person")
List<Person> getAll();
@Query("SELECT * FROM person WHERE feature = :feature")
List<Person> getByFeature(String feature);
}
AppDb.java
import androidx.room.Database;
import androidx.room.RoomDatabase;
@Database(
version = 1,
exportSchema = false,
entities = {Person.class}
)
public abstract class AppDb extends RoomDatabase {
public abstract PersonDao personDao();
}
解决方案
一个值与任何其他值null
都是唯一的null
,这就是为什么不会UNIQUE
发生约束冲突而必须进行替换的原因。
您可以使您的feature
字段@NonNull
使 null 不是有效值,如果它为空,那么您可以使用默认/魔术值,例如"NONE"
.
或者,如果您不真正使用id
,则可以将其删除并更改PRIMARY KEY
为name
字段,以便Person
替换具有相同名称但不同功能的插入。
推荐阅读
- gitlab-ci-runner - GitLab CI/CD yml 缓存不会成功
- android - 如何在 Common Utils 中使用带有按钮的静态对话框
- python - Pandas:转换数据框以显示原始数据框中是否存在值组合
- cors - 向 HTTP 请求添加更多标头时出错
- mysql - 无法为 mariadb 客户端使用 SSL 和 TLS 连接
- mxgraph - 如何将多个步骤合并为一个撤消/重做?
- javascript - Laravel 没有获取所有请求数据
- arduino - Arduino兼容芯片,无需晶体进行串行通信
- html - Django 和 HTML:导航栏周围多余空间的问题
- php - 解析错误:语法错误,第 13 行 E:\xampp\htdocs\study\connect.php 中的意外“值”(T_STRING)