Android-Room數(shù)據(jù)庫(kù)(介紹)
Android-Room數(shù)據(jù)庫(kù)-多表查詢(Relationships)
Android—Room自定義類(lèi)型(TypeConverter)
Android—Room?數(shù)據(jù)庫(kù)遷移(Migration)
前言
平常咱們使用數(shù)據(jù)庫(kù)的時(shí)候,基本操作都差不太多,增
,刪
,改
,查
,但如果操作不同的數(shù)據(jù)時(shí),就需要寫(xiě)較多的重復(fù)的代碼,僅僅是因?yàn)椴僮鞯念?lèi)對(duì)象變化了。下面咱們就通過(guò)泛型去封裝一層BaseDao
,減少后期的模板代碼。Room
的普通用法請(qǐng)看上面的鏈接。
封裝
當(dāng)您看完了上面的基本用法后,我相信下面的代碼對(duì)于您來(lái)說(shuō)也沒(méi)什么難度了。
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)的,無(wú)需手動(dòng)賦值)
*/
@Delete
abstract fun delete(obj: T)
/**
* 根據(jù)對(duì)象中的主鍵更新(主鍵是自動(dòng)增長(zhǎng)的,無(wú)需手動(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)
}
/**
* 分頁(yè)查詢,支持傳入多個(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)
}
/**
* 降序分頁(yè)查詢
*/
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è)常量,這里就無(wú)法通過(guò)泛型去解決,所以就使用了SupportSQLiteQuery
類(lèi)和@RawQuery
注解,這樣咱們就可以通過(guò)sql
語(yǔ)句來(lái)封裝一些通用的操作,就解決了Query
注解無(wú)法直接使用泛型的問(wèn)題,詳細(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ì)象類(lèi)型即可,通用的操作已封裝在上層,無(wú)需再重復(fù)寫(xiě)了
構(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
從日志可以看出,這樣封裝是沒(méi)什么問(wèn)題的,好了,今天的內(nèi)容到這就結(jié)束了。有什么問(wèn)題,歡迎留言。