Android—Room 通用封裝

Android-Room數(shù)據(jù)庫(介紹)

Android-Room數(shù)據(jù)庫-多表查詢(Relationships)

Android—Room自定義類型(TypeConverter)

Android—Room?數(shù)據(jù)庫遷移(Migration)

前言

平常咱們使用數(shù)據(jù)庫的時(shí)候,基本操作都差不太多窘拯,闷沥,钝腺,鞍帝,脆炎,但如果操作不同的數(shù)據(jù)時(shí)窑多,就需要寫較多的重復(fù)的代碼豆励,僅僅是因?yàn)椴僮鞯念悓?duì)象變化了烟央。下面咱們就通過泛型去封裝一層BaseDao统诺,減少后期的模板代碼。Room的普通用法請(qǐng)看上面的鏈接疑俭。

封裝

當(dāng)您看完了上面的基本用法后粮呢,我相信下面的代碼對(duì)于您來說也沒什么難度了。

abstract class BaseDao<T> {
    /**
     * 添加單個(gè)對(duì)象
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(obj: T): Long

    /**
     * 添加數(shù)組對(duì)象數(shù)據(jù)
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    abstract fun insert(vararg objs: T): LongArray?

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

    /**
     * 根據(jù)對(duì)象中的主鍵刪除(主鍵是自動(dòng)增長(zhǎng)的,無需手動(dòng)賦值)
     */
    @Delete
    abstract fun delete(obj: T)

    /**
     * 根據(jù)對(duì)象中的主鍵更新(主鍵是自動(dòng)增長(zhǎng)的啄寡,無需手動(dòng)賦值)
     */
    @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)
    }

    /**
     * 分頁查詢豪硅,支持傳入多個(gè)字段,但必須要按照順序傳入
     * key = value挺物,key = value 的形式懒浮,一一對(duì)應(yīng)(可以使用 stringbuilder 去構(gòu)造一下,這里就不演示了)
     */
    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>?
}

因?yàn)?code>Room的Query注解需要一個(gè)常量识藤,這里就無法通過泛型去解決砚著,所以就使用了SupportSQLiteQuery類和@RawQuery注解,這樣咱們就可以通過sql語句來封裝一些通用的操作痴昧,就解決了Query注解無法直接使用泛型的問題稽穆,詳細(xì)用法請(qǐng)看上面的方法。

使用

@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)"
    }
}
@Dao
abstract class StudentDao : BaseDao<Person>() {

}

這里咱們只要去繼承BaseDao然后傳入需要操作的對(duì)象類型即可赶撰,通用的操作已封裝在上層舌镶,無需再重復(fù)寫了

構(gòu)建 RoomDatabase

@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()
        }

    }
}

構(gòu)建 DBManager

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")
    }
}

使用方法

            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)

查詢

 val findAll = getInstance(applicationContext).findAll()
   if (findAll != null) {
        for (i in findAll) {
          Log.d(TAG, "obj-->${i}")
      }
  }
查詢.png

從日志可以看出,這樣封裝是沒什么問題的豪娜,好了餐胀,今天的內(nèi)容到這就結(jié)束了。有什么問題侵歇,歡迎留言骂澄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惕虑,隨后出現(xiàn)的幾起案子坟冲,更是在濱河造成了極大的恐慌,老刑警劉巖溃蔫,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件健提,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伟叛,警方通過查閱死者的電腦和手機(jī)私痹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來统刮,“玉大人紊遵,你說我怎么就攤上這事〗拿桑” “怎么了暗膜?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鞭衩。 經(jīng)常有香客問我学搜,道長(zhǎng)娃善,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任瑞佩,我火速辦了婚禮聚磺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炬丸。我一直安慰自己瘫寝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布御雕。 她就那樣靜靜地躺著矢沿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酸纲。 梳的紋絲不亂的頭發(fā)上捣鲸,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音闽坡,去河邊找鬼栽惶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛疾嗅,可吹牛的內(nèi)容都是我干的外厂。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼代承,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼汁蝶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起论悴,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤掖棉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后膀估,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幔亥,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年察纯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了帕棉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饼记,死狀恐怖香伴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情具则,我是刑警寧澤瞒窒,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站乡洼,受9級(jí)特大地震影響崇裁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜束昵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一拔稳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锹雏,春花似錦巴比、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佣耐,卻和暖如春政勃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兼砖。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工奸远, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人讽挟。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓懒叛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親耽梅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子薛窥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容