ROOM数据库的使用与升级

项目中使用了GreenDao创建数据库,建立了一个库并在其中生成了2个表,现在做整体优化,想使用Room创建数据库,毕竟Room是google官方产品,还是值得尝试一波的。

一:对于Room的使用,关注三个点:

1.创建Entity:直接上代码(部分代码省略)

第一个Entity

@Entity(tableName = "login_history_table")
public class LoginHistory {
    @PrimaryKey(autoGenerate = true)
    Long id;
 
    @ColumnInfo
    private String account;
 
    @ColumnInfo
    private String pwd;
 
    @ColumnInfo
    private String name;
    @ColumnInfo
    private String quickLoginToken;
    @ColumnInfo
    private String token;
    @ColumnInfo
    private String photo;
    @ColumnInfo
    private int userId;
    @ColumnInfo
    private long time;
    
    @ColumnInfo
    private int loginState = 0;
  
    @ColumnInfo
    private int isInvalid = 0;
 
}

第二个Entity

@Entity(tableName = "stat_event")
data class StatEvent(
        @PrimaryKey(autoGenerate = true) val id: Int,
        @ColumnInfo(name = "actionCode")
        var actionCode: String? = null,
        @ColumnInfo(name = "userId")
        var userId: Int? = null,
        @ColumnInfo(name = "reportTime")
        var reportTime: Long? = null,
        @ColumnInfo(name = "params1")
        var params1: String? = null,
        @ColumnInfo(name = "params2")
        var params2: String? = null,
) {
  
}


2.创建对应Dao:
 

@Dao
interface LoginHistoryDao {
 
    @Insert
    fun insert(history: LoginHistory)
 
    @Delete
    fun delete(history: LoginHistory)
 
    @Update
    fun update(history: LoginHistory)
 
    @Query("select * from login_history_table order by time desc")
    fun getAllHistory(): List?
 
    @Query("select * from login_history_table  order by time desc limit :count")
    fun getHistoryLimit(count: Int): List?
 
    @Query("select * from login_history_table where userId=:id")
    fun getHistory(id: Int): LoginHistory?
}
@Dao
interface StatEventDao {
 
    @Insert
    fun insert(list: List)
 
    @Insert()
    fun insert(event: StatEvent)
 
    @Query("select * from stat_event")
    fun getAllEvent(): List?
 
    @Delete
    fun deleteAll(events: List?)
}

3.创建数据库db单例类:

@Database(entities = [StatEvent::class,LoginHistory::class], version = 2)
abstract class StatEventDb : RoomDatabase() {
    abstract fun statEventDao(): StatEventDao
  
    abstract fun loginHistoryDao(): LoginHistoryDao
 
    companion object {
        private var instance: StatEventDb? = null
 
        fun get(context: Context): StatEventDb {
            if (instance == null) {
                //注释2
                instance = Room.databaseBuilder(context, StatEventDb::class.java, "stat_event.db")
                        .fallbackToDestructiveMigration()
                     
                        //是否允许在主线程进行查询
                        .allowMainThreadQueries()
                        .build()
            }
            return instance!!
        }
 
    }
}

4.使用示例:

StatEventDb.get(BaseApplication.getInstance()).statEventDao().insert(event)
二:升级:

我们做个示例,针对于其中一个表做升级,对

login_history_table  表格增加一个字段,testVersion。
直接上代码:

1.Entity改变:

@Entity(tableName = "login_history_table")
public class LoginHistory {
    @PrimaryKey(autoGenerate = true)
    Long id;
 
    @ColumnInfo
    private String account;//邮箱或者手机号码
 
    @ColumnInfo
    private String pwd;
 
    @ColumnInfo
    private String name;
    @ColumnInfo
    private String quickLoginToken;
    @ColumnInfo
    private String token;
    @ColumnInfo
    private String photo;
    @ColumnInfo
    private int userId;
    @ColumnInfo
    private long time;
    //0:未登录,1:已登录,2:正在登陆中
    @ColumnInfo
    private int loginState = 0;
    //0:正常,1:失效
    @ColumnInfo
    private int isInvalid = 0;
 
    @ColumnInfo
    private long testVersion=0;
}

2.DB类的改变:

@Database(entities = [StatEvent::class,  LoginHistory::class], version = 3)
abstract class StatEventDb : RoomDatabase() {
    abstract fun statEventDao(): StatEventDao
    abstract fun luckyCartDao(): LuckyCartDao
    abstract fun loginHistoryDao(): LoginHistoryDao
 
    companion object {
        private var instance: StatEventDb? = null
 
        fun get(context: Context): StatEventDb {
            if (instance == null) {
                //注释2
                instance = Room.databaseBuilder(context, StatEventDb::class.java, "stat_event.db")
                        .fallbackToDestructiveMigration()
                          //添加升级策略
                        .addMigrations(Migration2_3())
                        //是否允许在主线程进行查询
                        .allowMainThreadQueries()
                        .build()
            }
            return instance!!
        }
 
    }
}

3.Migration2_3类:

class Migration2_3 : Migration(2, 3) {
    override fun migrate(database: SupportSQLiteDatabase) {
 
        database.execSQL("CREATE TABLE temp_Stat_event (" +
                "id INTEGER PRIMARY KEY NOT NULL," +
                "actionCode TEXT," +
                "userId INTEGER," +
                "reportTime INTEGER," +
                "params1 TEXT," +
                "params2 TEXT)");
        database.execSQL("INSERT INTO temp_Stat_event (id, actionCode, userId,reportTime,params1,params2) " +
                "SELECT id, actionCode, userId,reportTime,params1,params2 FROM stat_event");
        database.execSQL("DROP TABLE stat_event");
        database.execSQL("ALTER TABLE temp_Stat_event RENAME TO stat_event");
 
 
 
        database.execSQL("CREATE TABLE temp_login_history_table (" +
                "id INTEGER PRIMARY KEY," +
                "account TEXT," +
                "pwd TEXT," +
                "name TEXT," +
                "quickLoginToken TEXT," +
                "token TEXT," +
                "photo TEXT," +
                "userId INTEGER," +
                "time INTEGER," +
                "loginState INTEGER NOT NULL DEFAULT null," +
                "isInvalid INTEGER NOT NULL DEFAULT null)" )
 
        database.execSQL("INSERT INTO temp_login_history_table (id, account, pwd,name,quickLoginToken,token,photo,userId,time,loginState,isInvalid) " +
                "SELECT id, account, pwd,name,quickLoginToken,token,photo,userId,time,loginState,isInvalid FROM login_history_table");
        database.execSQL("DROP TABLE login_history_table");
        database.execSQL("CREATE TABLE login_history_table (" +
                "id INTEGER PRIMARY KEY," +
                "account TEXT," +
                "pwd TEXT," +
                "name TEXT," +
                "quickLoginToken TEXT," +
                "token TEXT," +
                "photo TEXT," +
                "userId INTEGER NOT NULL," +
                "time INTEGER NOT NULL," +
                "loginState INTEGER NOT NULL DEFAULT null," +
                "isInvalid INTEGER NOT NULL DEFAULT null,"+
                "testVersion INTEGER NOT NULL )")
 
        database.execSQL("INSERT INTO login_history_table (id, account, pwd,name,quickLoginToken,token,photo,userId,time,loginState,isInvalid,testVersion) " +
                "SELECT id, account, pwd,name,quickLoginToken,token,photo,userId,time,loginState,isInvalid ,0 FROM temp_login_history_table");
        database.execSQL("DROP TABLE temp_login_history_table");
    }
}

对于Migration2_3说明:

对于版本2升级到版本3时,重新创建需要改变的表,创建新的字段,并把旧数据保存进去。对于不改变的表不用执行sql语句,所以上述的stat_event表可以不用执行sql。  上述的sql语句也有部分可以优化。

遇到的报错日志:

ROOM数据库的使用与升级_第1张图片

 对于上述报错,仔细看下错误信息会发现,上面是Expected期望的数据类型,下面是Found执行发现的数据类型,对比会发现不太一样,直接按照Expected的去更改就行。

以上是Room使用的一波体验,希望能给大家有所帮助。

 


————————————————
版权声明:本文为CSDN博主「卖火柴的大兄弟」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42789174/article/details/123236639

你可能感兴趣的:(jetpack,database,数据库,java,开发语言)