我们使用Room库,往表中插入数据Model时,我们已经添加注解o@PrimaryKey(autoGenerate = true)o设置了Model的属性 xxId作为自动生成的id。
然后我们在Dao层进行数据插入时,需要传入一个Model对象,比如:
@Insert
suspend fun insertStudents(vararg students: Student)
那么也就是说,我们需要手动实例化一个Model对象出来,而xxId本身就是作为这个Model的属性,所以我们不得不实例化时,传入一个xxId进去,这也就失去了自动生成的效果。
Java语言:
Java语言解决方案很简单,就是新增一个没有xxId的Model的构造方法。
@Entity
Class Student() {
@PrimaryKey(autoGenerate = true) private int xxId;
@ColumnInfo(name = "student_name") private String name;
Student(int c_id, String c_name) {
this.xxId = c_id;
this.name = c_name;
}
// 我们新增一个构造方法,并添加@ignore注解,让Room忽略这个构造方法
@Ignore
Student(String c_name) {
this.name = c_name
}
}
插入数据时,我们就使用新增的构造函数实例化对象。
Student student = new Student("jack");
xxDao.insert(student);
Kotlin语言:
Kotlin语言稍微特殊一点,Kotlin语法中,类的构造方法分为主构造方法和次构造方法,所以我们如果也用新增构造方法的话就会有一点小问题,因为次构造方法都需要直接或间接继承主构造方法。(应该不能叫继承,重载?有点忘记了,之后重新看一下文档)
@Entity
Class Student(
@PrimaryKey(autoGenerate = true) val xxId: Int,
@ColumnInfo(name = "student_name") val name: String,
) {
constructor(name: String) : this(xxxx需要有id填入, name)
}
所以目前我想到的方法就是 将xxId设置为可空,同时给予默认的null值。
也就是像这个样子:
@Entity
Class Student(
@PrimaryKey(autoGenerate = true) val xxId: Int? = null,
@ColumnInfo(name = "student_name") val name: String,
)
// 那么我们在往表中插入数据时就可以这样写:
val student = Student("jack")
xxDao.insert(student)
两种方法的实现可能都不是很妥, 因为xxId本身在类属性的声明中视为可空,这个似乎有些违背ID本身的定义:唯一的,不可为空的。
但你可能会说,“虽然我们声明定义的xxxId是可空的,但是插入表时,room会自动生成一个增加1的Id,也就不会有空的情况了。”
但我个人觉得,Kotlin 可空性修饰符的意义就是为了避免空指针的出现,只要声明为可空,我们就可以给这个属性设置为null,所以也就在程序逻辑中增加了 判空的处理,而这个判空处理目前看起来并没有意义。