前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Android—Room 通用封装

Android—Room 通用封装

作者头像
code_horse
发布2021-05-06 15:30:07
发布2021-05-06 15:30:07
2.3K10
代码可运行
举报
文章被收录于专栏:Android NoteAndroid Note
运行总次数:0
代码可运行

前言

平常咱们使用数据库的时候,基本操作都差不太多,,但如果操作不同的数据时,就需要写较多的重复的代码,仅仅是因为操作的类对象变化了。下面咱们就通过泛型去封装一层BaseDao,减少后期的模板代码。Room的普通用法请看上面的链接。

封装

当您看完了上面的基本用法后,我相信下面的代码对于您来说也没什么难度了。

代码语言:javascript
代码运行次数:0
复制
abstract class BaseDao<T> {
    /**
     * 添加单个对象
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(obj: T): Long

    /**
     * 添加数组对象数据
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(vararg objs: T): LongArray?

    /**
     * 添加对象集合
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(personList: List<T>): List<Long>

    /**
     * 根据对象中的主键删除(主键是自动增长的,无需手动赋值)
     */
    @Delete
    abstract fun delete(obj: T)

    /**
     * 根据对象中的主键更新(主键是自动增长的,无需手动赋值)
     */
    @Update
    abstract fun update(vararg obj: T): Int

    fun deleteAll(): Int {
        val query = SimpleSQLiteQuery(
            "delete from $tableName"
        )
        return doDeleteAll(query)
    }

    fun findAll(): List<T>? {
        val query = SimpleSQLiteQuery(
            "select * from $tableName"
        )
        return doFindAll(query)
    }

    fun find(id: Long): T? {
        val query = SimpleSQLiteQuery(
            "select * from $tableName where id = ?", arrayOf<Any>(id)
        )
        return doFind(query)
    }

    /**
     * [params] 列名
     * [value] 列的值
     */
    fun deleteByParams(params: String, value: String): Int {
        val query = SimpleSQLiteQuery("delete from $tableName where $params='${value}'")
        Log.d("ez", "deleteByParams: ${"delete from $tableName where $params='${value}'"}")
        return doDeleteByParams(query)
    }

    /**
     * 分页查询,支持传入多个字段,但必须要按照顺序传入
     * key = value,key = value 的形式,一一对应(可以使用 stringbuilder 去构造一下,这里就不演示了)
     */
    fun doQueryByLimit(vararg string: String, limit: Int = 10, offset: Int = 0): List<T>? {
        val query =
            SimpleSQLiteQuery("SELECT * FROM $tableName WHERE ${string[0]} = '${string[1]}' limit $limit offset $offset")
        return doQueryByLimit(query)
    }

    /**
     * 降序分页查询
     */
    fun doQueryByOrder(vararg string: String, limit: Int = 10, offset: Int = 10): List<T>? {
        val query =
            SimpleSQLiteQuery("SELECT * FROM $tableName ORDER BY ${string[0]} desc limit '${limit}' offset '${offset}'")
        return doQueryByLimit(query)
    }

      /**
      * 获取表名
       */
    val tableName: String
        get() {
            val clazz = (javaClass.superclass.genericSuperclass as ParameterizedType)
                .actualTypeArguments[0] as Class<*>
            val tableName = clazz.simpleName
            Log.d("ez", "getTableName: -->$tableName")
            return tableName
        }

    @RawQuery
    protected abstract fun doFindAll(query: SupportSQLiteQuery?): List<T>?

    @RawQuery
    protected abstract fun doFind(query: SupportSQLiteQuery?): T

    @RawQuery
    protected abstract fun doDeleteAll(query: SupportSQLiteQuery?): Int

    @RawQuery
    protected abstract fun doDeleteByParams(query: SupportSQLiteQuery?): Int

    @RawQuery
    protected abstract fun doQueryByLimit(query: SupportSQLiteQuery?): List<T>?

    @RawQuery
    protected abstract fun doQueryByOrder(query: SupportSQLiteQuery?): List<T>?
}

因为RoomQuery注解需要一个常量,这里就无法通过泛型去解决,所以就使用了SupportSQLiteQuery类和@RawQuery注解,这样咱们就可以通过sql语句来封装一些通用的操作,就解决了Query注解无法直接使用泛型的问题,详细用法请看上面的方法。

使用

代码语言:javascript
代码运行次数:0
复制
@Entity
class Person {
    @PrimaryKey(autoGenerate = true)
    var id: Long?
    var bh: String 
    var name: String? = null
    var loginName: String? = null
    var feature: ByteArray? = null
    var isPolice: Boolean = false

    constructor(
        id: Long? = null,
        name: String?,
        feature: ByteArray? = null,
        bh: String,
        loginName: String? = null,
        isPolice: Boolean = false
    ) {
        this.id = id
        this.name = name
        this.feature = feature
        this.bh = bh
        this.loginName = loginName
        this.isPolice = isPolice
    }

    override fun toString(): String {
        return "Person(id=$id, bh=$bh, name=$name,loginName=$loginName, isPolice=$isPolice)"
    }
}
代码语言:javascript
代码运行次数:0
复制
@Dao
abstract class StudentDao : BaseDao<Person>() {

}

这里咱们只要去继承BaseDao然后传入需要操作的对象类型即可,通用的操作已封装在上层,无需再重复写了

构建 RoomDatabase

代码语言:javascript
代码运行次数:0
复制
@Database(entities = [Person::class],version = 1,exportSchema = false)
abstract class DBFactory :RoomDatabase(){

    abstract fun getStudent():StudentDao

    companion object{
        private const val DB_NAME = "DBFactory.db"
        @Volatile
        private var dbFactory:DBFactory?=null

        @Synchronized
        fun getInstance(context: Context):DBFactory{
            if (dbFactory == null) {
                dbFactory = create(context)
            }
            return dbFactory!!
        }

        fun create(context: Context):DBFactory{
            return Room.databaseBuilder(context,DBFactory::class.java, DB_NAME).build()
        }

    }
}

构建 DBManager

代码语言:javascript
代码运行次数:0
复制
class DBManager(context:Context) {

    private var mContext: Context = context

    companion object{
        @Volatile
        private var instance:DBManager?=null
        @Synchronized
        fun getInstance(context: Context):DBManager{
            if(instance == null){
                instance = DBManager(context)
            }
            return instance!!
        }
    }

    fun insertPerson(name: String?, feature: ByteArray?=null,bh:String?,loginName:String?, isPolice:Boolean?):Long {
        val person = Person(name = name,feature = feature,bh = bh!!,loginName = loginName,isPolice = isPolice!!)
        return DBFactory.getInstance(mContext).getStudent().insert(person)
    }

    fun deleteByParams(params:String,value:String):Int{
        return DBFactory.getInstance(mContext).getStudent().deleteByParams(params,value)
    }

    fun countPerson():Int?{
        return DBFactory.getInstance(mContext).getStudent().findAll()?.size
    }

    fun findAll():List<Person>?{
        return DBFactory.getInstance(mContext).getStudent().findAll()
    }

    fun doQueryByLimit():List<Person>?{
        return DBFactory.getInstance(mContext).getStudent().doQueryByLimit("name","aa")
    }
}

使用方法

代码语言:javascript
代码运行次数:0
复制
            getInstance(applicationContext).insertPerson("aa", null, "aa11", "aa11", false)
            getInstance(applicationContext).insertPerson("bb", null, "bb11", "bb11", false)
            getInstance(applicationContext).insertPerson("cc", null, "cc11", "cc11", false)
            getInstance(applicationContext).insertPerson("dd", null, "dd11", "dd11", false)
            getInstance(applicationContext).insertPerson("ee", null, "ee11", "ee11", false)
            getInstance(applicationContext).insertPerson("ff", null, "ff11", "ff11", false)
            getInstance(applicationContext).insertPerson("gg", null, "gg11", "gg11", false)
            getInstance(applicationContext).insertPerson("hh", null, "hh11", "hh11", false)
            getInstance(applicationContext).insertPerson("ii", null, "ii11", "ii11", false)
            getInstance(applicationContext).insertPerson("jj", null, "jj11", "jj11", false)
            getInstance(applicationContext).insertPerson("kk", null, "kk11", "kk11", false)
            getInstance(applicationContext).insertPerson("ll", null, "ll11", "ll11", false)
            getInstance(applicationContext).insertPerson("mm", null, "mm11", "mm11", false)
            getInstance(applicationContext).insertPerson("nn", null, "nn11", "nn11", false)

查询

代码语言:javascript
代码运行次数:0
复制
 val findAll = getInstance(applicationContext).findAll()
   if (findAll != null) {
        for (i in findAll) {
          Log.d(TAG, "obj-->${i}")
      }
  }

查询.png

从日志可以看出,这样封装是没什么问题的,好了,今天的内容到这就结束了。有什么问题,欢迎留言。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 封装
  • 使用
  • 构建 RoomDatabase
  • 构建 DBManager
  • 使用方法
  • 查询
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档