平常咱们使用数据库的时候,基本操作都差不太多,增,删,改,查,但如果操作不同的数据时,就需要写较多的重复的代码,仅仅是因为操作的类对象变化了。下面咱们就通过泛型去封装一层baseDao,减少后期的模板代码。
二、封装abstract class baseDao{ @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 ): List @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 ? { val query = SimpleSQLiteQuery( "select * from $tableName" ) return doFindAll(query) } fun find(id: Long): T? { val query = SimpleSQLiteQuery( "select * from $tableName where id = ?", arrayOf (id) ) return doFind(query) } 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) } fun doQueryByLimit(vararg string: String, limit: Int = 10, offset: Int = 0): List ? { 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 ? { 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 ? @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 ? @RawQuery protected abstract fun doQueryByOrder(query: SupportSQLiteQuery?): List ? }
三、使用因为Room的Query注解需要一个常量,这里就无法通过泛型去解决,所以就使用了SupportSQLiteQuery类和@RawQuery注解,这样咱们就可以通过sql语句来封装一些通用的操作,就解决了Query注解无法直接使用泛型的问题,详细用法请看上面的方法。
@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() { }
这里咱们只要去继承baseDao然后传入需要操作的对象类型即可,通用的操作已封装在上层,无需再重复写了
构建 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() } } }