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