Android Room 初探,插入,查询,删除,更新,升级

Android Jetpack ROOM 数据库框架使用

 

  • Android Jetpack ROOM 数据库框架使用
    • 前言
    • 配置dependencies
    • 配置实体类
    • 配置DAO
    • 配置DataBase单例类
    • 操作数据库
      • 插入数据
      • 查询数据
      • 删除数据
      • 更新数据
    • 升级数据库

 

前言

  • 谷歌推出Jetpack已经好久了,之前一直断断续续的使用过一些,但是都没有整理过.学习就要记笔记或者在项目中实践,不然很容易时间长的话忘记
  • 谷歌文档地址
  • 版本说明 大家最好使用稳定版本,之前AndroidX 升级新版本遇到的5.15.0的系统WebView必崩的问题,我建议使用exclude同意一下AdnroidX的版本

配置dependencies

  • 使用Kotlin记得相关Module使用apt apply plugin: 'kotlin-kapt'
    dependencies {
      def room_version = "2.2.3"

      implementation "androidx.room:room-runtime:$room_version"
      annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor

      // optional - Kotlin Extensions and Coroutines support for Room
      implementation "androidx.room:room-ktx:$room_version"

      // optional - RxJava support for Room
      implementation "androidx.room:room-rxjava2:$room_version"

      // optional - Guava support for Room, including Optional and ListenableFuture
      implementation "androidx.room:room-guava:$room_version"

      // Test helpers
      testImplementation "androidx.room:room-testing:$room_version"
    }
    
  • ROOM架构图(摘自谷歌官方文档)

​​​​​​​Android Room 初探,插入,查询,删除,更新,升级_第1张图片

 

配置实体类

  1. @PrimaryKey表示主键,autoGenerate属性表示是否自增
  2. @ColumnInfo表示指定列名
  3. @Ignore表示忽略此字段,表中就没有此字段
@Entity(tableName = "user")
data class User(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    val id: Long,
    @ColumnInfo(name = "name")
    var name: String?,
    @ColumnInfo(name = "address")
    var address: String?,
    @Ignore
    var birthday: String?
)

配置DAO

@Dao
interface UserDao {
    /**
     * 查询所有用户
     */
    @Query("SELECT * FROM user")
    fun getAll(): List

    /**
     * 根据id查询到某一个用户
     */
    @Query("SELECT * FROM user WHERE id=(:uid) ")
    fun loadAllById(uid: Int): User

    /**
     * 根据用户id数组查询到一批用户
     */
    @Query("select * from user where id in (:ids)")
    fun loadAllByIds(ids: IntArray): List

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUser(user: User?)
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUser(users: List)
    @Insert
    fun deleteUser(user: User?)
    //只返回name的子集  
    @Query("SELECT name From user")
    fun loadFullName(): List
}

data class NameTuple(
    @ColumnInfo(name = "name") var name: String?
)

配置DataBase单例类

  • 操作数据库请在子线程操作,UI线程刷新,

  • 当然Room也支持在主线程操作,不过不建议,如果需要声明在主线程操作,记得声明

    fallbackToDestructiveMigration()属性

@Database(entities = [User::class], version = 1)
abstract class UserDataBase : RoomDatabase() {

    companion object {
        @Volatile
        private var INSTANCE: UserDataBase? = null

        fun getInstance(context: Context): UserDataBase =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: (
                        Room.databaseBuilder(
                            context.applicationContext,
                            UserDataBase::class.java,
                            "user_database.db"
                        ).allowMainThreadQueries()
                            .fallbackToDestructiveMigration()
                            .build()
                        ).also {
                    INSTANCE = it
                }
            }
    }

    abstract fun userDao(): UserDao
}

操作数据库

插入数据

  • 插入一条数据

  • OnConflictStrategy.REPLACE表示插入的时候有该数据的情况下会直接替换

interface UserDao{
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUser(user: User?)
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUser(users: List)
}
UserDataBase.getInstance(this).userDao().insertUser(User(1, "小明", "北京朝阳区"))
UserDataBase.getInstance(this).userDao().insertUser(User(2, "小红", "北京通州区"))
id name address
1 小明 北京朝阳区
2 小红 北京通州区
  • 插入一批数据
val userList = arrayListOf(User(3, "小张", "北京丰台区"),User(4, "小王", "北京海淀区"))
UserDataBase.getInstance(this).userDao().insertUser(userList)
id name address
1 小明 北京朝阳区
2 小红 北京通州区
3 小张 北京丰台区
4 小王 北京海淀区

查询数据

  • 可以参照sql语句做一些条件查询,下面是一些基本的简单查找
interface UserDao{
    @Query("SELECT * FROM user")
    fun getAll(): List
     /**
     * 根据id查询到某一个用户
     */
    @Query("SELECT * FROM user WHERE id  = (:uid) ")
    fun loadAllById(uid: Int): User

    /**
     * 根据用户id数组查询到一批用户
     */
    @Query("select * from user where id in (:ids)")
    fun loadAllByIds(ids: IntArray): List
	/**
     * 查询到的用户只返回user表中的name列信息
     */
    @Query("SELECT name From user")
    fun loadFullName(): List
}
UserDataBase.getInstance(this).userDao().getAll()
UserDataBase.getInstance(this).userDao().loadAllById(1)
UserDataBase.getInstance(this).userDao().loadAllByIds(intArrayOf(1,2))

删除数据

UserDataBase.getInstance(this).userDao().deleteUser(User(1, "小明", "北京朝阳区"))
//同样也可以传入list批量删除

更新数据

UserDataBase.getInstance(this).userDao().updateUser(User(2, "小小红", "上海"))

升级数据库

  • 需要在Databaseversion+1
@Database(entities = [User::class], version = 2)
abstract class UserDataBase : RoomDatabase() {}
  • 也可以直接在构建DataBase类的时候声明fallbackToDestructiveMigration()属性,不过这样升级会导致之前的数据情况

  • version增加的同事,提供Migration,这样会保证数据的正常,记得在对应Entity也增加对应的属性

  • Migration也支持直接从version1->version4,不过我感觉还是一步一步升级比较符合,避免未知错误

    fun getInstance(context: Context): UserDataBase =
                INSTANCE ?: synchronized(this) {
                    INSTANCE ?: (
                            Room.databaseBuilder(
                                context.applicationContext,
                                UserDataBase::class.java,
                                "user_database.db"
                            ).allowMainThreadQueries()
                             .addMigrations(migration)
                             .build()
                            ).also {
                        INSTANCE = it
                    }
                }
    
            private val migration = object : Migration(1, 2) {
                override fun migrate(database: SupportSQLiteDatabase) {
                    database.execSQL(
                        "ALTER TABLE user "
                                + " ADD COLUMN age INTEGER"
                    )
                }
            }

你可能感兴趣的:(Android,Jetpack)