a、采坑之新增表:
1、假设在表UserModel 实体里有一个int字段 id 是主键自增的,在migrate()方法中执行建表SQL语句时,id需要指定 NOT NULL,否则会报异常:java.lang.IllegalStateException: Migration didn't properly handle UserModel 。
2、新建表UserModel 实体时,可以含有boolean类型的字段,但是在migrate()方法中执行建表SQL语句时,该字段不能为BOOLEAN类型的,需要用 INTEGER 替换,且需要加上 NOT NULL,如果不指定默认值,则系统默认为1也就是true。
3、新建表时,在migrate()方法中执行建表SQL语句时,不需要为字段加上默认值即:DEFAULT XXX
b、采坑之新增表字段:
1、假设新增ctTime 字段的类型是int 或 long,在表UserModel 实体里, , 则在migrate()方法中执行SQL语句的时候ctTime 声明需为 INTEGER 类型,并且要加上 NOT NULL DEFAULT 0 ,如:"ALTER TABLE UserModel ADD COLUMN ctTime INTEGER NOT NULL DEFAULT 0" ,
如果不加 NOT NULL 则会报这个异常:java.lang.IllegalStateException: Migration didn't properly handle UserModel ,因为Room会默认根据你的数据实体UserModel来创建该字段的notNull=true,所以必须加上。
如果不加 DEFAULT 0 则会报这个异常:android.database.sqlite.SQLiteException: Cannot add a NOT NULL column with default value NULL (code 1):
2、在migrate()方法中执行SQL语句新增某字段时,该字段不能为BOOLEAN类型的,需要用 INTEGER 替换,如果不指定默认值,则系统默认为1也就是true,但是在写表UserModel 实体时,时可以定义Boolean类型的变量的,Room会自己转化为INTEGER。
3、新增某字段类型为 String 时,在migrate()方法中执行SQL语句,该字段用 TEXT 类型进行声明;
综合上述情况(a和b):创建Entity实体时,把类型为 int 或 long 或 boolean 的字段用 Integer 去声明,在SQL语句声明时,每个integer字段就 不用加上 NOT NULL,这样创建的表的 Integer 类型的字段,默认值为 NULL,如:database.execSQL("CREATE TABLE IF NOT EXISTS 'UserModel ' ('id' INTEGER NOT NULL PRIMARY KEY autoincrement, 'uid' INTEGER, 'name' TEXT, 'age' INTEGER, 'isMarry' INTEGER)");
另外还有2个注解需要注意如下:
注解 @Ignore 代表字段不会映射到表的 Columns中;
注解 @Embedded 代表创建嵌套表对象;