寫在前面
最近在看Room,這裏簡單記錄一下,方便以後回顧學習,理論就不說了,理論知識這裏自行了解。
準備工作
-
環境配置
room_version = “2.2.0-alpha01”
implementation “androidx.room:room-runtime:$room_version”
kapt “androidx.room:room-compiler: $room_version”
implementation “androidx.room:room-ktx: $room_version” -
基礎結構
dao包內存放Dao文件,entity包負責存放實體類,AppDataBase是DataBase的實現類。
建立一個用戶表
這裏我建立一個用戶表,包含以下字段,自增_id,姓名name,年齡age,代碼如下
@Entity
data class User(
@PrimaryKey(autoGenerate = true) val _id:Int,
val name:String,
val age:Int
)
接下來建立一個用戶表的操作類UserDao,代碼如下
@Dao
interface UserDao {
/**
* 添加一個用戶
*/
@Insert
fun insert(user: User)
/**
* 刪除一個用戶
*/
@Delete
fun delete(user:User)
/**
* 查詢所用用戶
*/
@Query("select * from User")
fun queryAll():List<User>
}
在DataBase中註冊下
//entities指定表,version指定版本
@Database(entities = arrayOf(User::class),version = 1)
abstract class AppDataBase :RoomDatabase(){
abstract fun getUserDao():UserDao
companion object{
private var instance:AppDataBase?=null
fun getInstance(context: Context):AppDataBase{
if (instance==null){
synchronized(AppDataBase::class){
if (instance==null){
instance=Room.databaseBuilder(context,AppDataBase::class.java,"room")
.build()
}
}
}
return instance!!
}
}
}
相關操作(注:不要在主線程操作,會報錯的!!!)
- 增加一個用戶
AppDataBase.getInstance(this).getUserDao().insert(User(name = "張三",age = 22))
- 查詢所有用戶
AppDataBase.getInstance(this).getUserDao().queryAll()
- 刪除一個用戶
AppDataBase.getInstance(this).getUserDao().delete(user)
給用戶表添加愛好(likes)字段
@Entity
@TypeConverters(StringConverter::class)
data class User(
@PrimaryKey(autoGenerate = true) val _id:Int=0,
val name:String,
val age:Int,
val likes:List<String>?
)
這裏需要用到類型轉換TypeConverters,需要寫一個StringConverter類,具體實現如下
class StringConverter {
@TypeConverter
fun listTostring(list:List<String>):String{
return Gson().toJson(list)
}
@TypeConverter
fun stringTolist(str:String?):List<String>?{
return Gson().fromJson<List<String>>(str, object : TypeToken<List<String>>() {
}.type)
}
}
UserDao中也要添加下@TypeConverters註解
@Dao
@TypeConverters(StringConverter::class)
interface UserDao {
...
}
然後數據庫版本升級
@Database(entities = arrayOf(User::class),version = 2)
abstract class AppDataBase :RoomDatabase(){
abstract fun getUserDao():UserDao
companion object{
private var instance:AppDataBase?=null
fun getInstance(context: Context):AppDataBase{
if (instance==null){
synchronized(AppDataBase::class){
if (instance==null){
instance=Room.databaseBuilder(context,AppDataBase::class.java,"room")
.addMigrations(object :Migration(1,2){
override fun migrate(database: SupportSQLiteDatabase) {
database.run {
execSQL("alter table User add COLUMN likes TEXT")
}
}
})
.build()
}
}
}
return instance!!
}
}
}
小提示:這個是添加的List< String >,你也可以將String替換爲其它類型哦,@TypeConverter與@TypeConverters的使用主要是將數據庫不存在的類型轉換爲數據庫存在的類型,你需要提供他們互轉的方法,定義轉化類。
添加索引並指定唯一性
現在呢,我想將姓名添加爲索引,並且是唯一的,需要這麼做
@Entity(indices = arrayOf(Index(value = arrayOf("name"),unique = true)))
@TypeConverters(StringConverter::class)
data class User(
...
)
由於表結構變化需要升級數據庫(注:entity一旦改變則需要升級數據庫)
@Database(entities = arrayOf(User::class),version = 3)
abstract class AppDataBase :RoomDatabase(){
abstract fun getUserDao():UserDao
companion object{
private var instance:AppDataBase?=null
fun getInstance(context: Context):AppDataBase{
if (instance==null){
synchronized(AppDataBase::class){
if (instance==null){
instance=Room.databaseBuilder(context,AppDataBase::class.java,"room")
.addMigrations(object :Migration(1,2){
override fun migrate(database: SupportSQLiteDatabase) {
database.run {
execSQL("alter table User add COLUMN likes TEXT")
}
}
},object :Migration(2,3){
override fun migrate(database: SupportSQLiteDatabase) {
database.run {
execSQL("create UNIQUE index index_User_name on User(name)")
}
}
})
.build()
}
}
}
return instance!!
}
}
}
這個時候再添加同姓名的數據則會報UNIQUE constraint failed: User.name 錯誤。
更新用戶信息
現在呢,我想將名字爲張三的用戶的年齡修改成23,怎麼做呢?
@Dao
@TypeConverters(StringConverter::class)
interface UserDao {
...
/**
*更新用戶年齡
**/
@Query("update user set age = :age where name = :name")
fun updateAgeByName(name:String,age:Int):Int
對,你沒有看錯,它使用的是@Query,返回值是Int。
結語
回顧一下,本文主要講述了Room建表,增、刪、改、查操作,字段類型轉換,添加索引,數據庫升級操作,都是一些比較基礎的東西,至於多表之間的操作,如通過添加外鍵實現一對多,多對多,@Relation的使用等之後再做總結。