增加了sqlite操作工具
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -4,7 +4,7 @@
|
||||
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
|
||||
<groovy codeStyle="LEGACY" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,5 +1,6 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
// buildToolsVersion rootProject.ext.android.buildToolsVersion
|
||||
@@ -30,6 +31,7 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
api rootProject.ext.dependencies.glide
|
||||
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
|
||||
implementation rootProject.ext.dependencies.glideanno
|
||||
implementation rootProject.ext.dependencies.glideokhttp3
|
||||
implementation rootProject.ext.dependencies.supportannos
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
package com.mogo.utils.sqlite
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import com.mogo.utils.sqlite.annotation.DbField
|
||||
import com.mogo.utils.sqlite.annotation.DbTable
|
||||
import java.lang.reflect.Field
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* <p>数据类操作实现</p>
|
||||
*Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
//T必须指明上界是Any且不为null,下面会用到反射获取对象实例,默认是Any?
|
||||
open class BaseDao<T : Any> : IBaseDao<T> {
|
||||
|
||||
//数据库操作的引用
|
||||
private var sqLiteDatabase: SQLiteDatabase? = null
|
||||
//要操作的数据实体的引用
|
||||
private var entityClass: Class<T>? = null
|
||||
//要操作的数据表名称
|
||||
private var tableName: String? = null
|
||||
//记录数据表是否存在
|
||||
private var isInit = false
|
||||
|
||||
//因为反射会消耗时间,这里使用缓存,进行性能优化
|
||||
//缓存空间(key-字段名,标注的自定义注解 value-成员变量)
|
||||
private var cacheField: HashMap<String, Field>? = null
|
||||
|
||||
override fun init(sqLiteDatabase: SQLiteDatabase, entityClass: Class<T>): Boolean {
|
||||
this.sqLiteDatabase = sqLiteDatabase
|
||||
this.entityClass = entityClass
|
||||
//自动建表(只创建一次)
|
||||
if (!isInit) {
|
||||
//获取表名
|
||||
tableName = entityClass.getAnnotation(DbTable::class.java).tableName
|
||||
|
||||
//如果数据库没有建立连接跳出操作防止异常信息
|
||||
if (!sqLiteDatabase.isOpen) {
|
||||
return false
|
||||
}
|
||||
|
||||
//执行Sql进行自动建表
|
||||
val createTableSql = getCreateTableSql()
|
||||
sqLiteDatabase.execSQL(createTableSql)
|
||||
|
||||
//初始化缓存空间
|
||||
cacheField = HashMap()
|
||||
initCacheField()
|
||||
|
||||
//标记已经创建过数据表
|
||||
isInit = true
|
||||
}
|
||||
|
||||
return isInit
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化字段缓存
|
||||
*/
|
||||
private fun initCacheField() {
|
||||
//1.取到所有的列名(查询一个空表获取表结构,不影响性能)
|
||||
if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) {
|
||||
val sqlQuery = "select * from $tableName limit 1,0"
|
||||
val cursor = sqLiteDatabase!!.rawQuery(sqlQuery, null)
|
||||
//获取所有的列名
|
||||
val columnNames = cursor.columnNames
|
||||
//关闭资源
|
||||
cursor.close()
|
||||
//2.取所有成员名
|
||||
val columnFields = entityClass!!.declaredFields
|
||||
//3.通过两层循环,进行对应关系建立
|
||||
columnNames.forEach ColumnFor@{ columnName ->
|
||||
columnFields.forEach FieldFor@{ columnField ->
|
||||
if (columnName == columnField.getAnnotation(DbField::class.java).fieldName) {
|
||||
columnField.isAccessible = true
|
||||
cacheField!![columnName] = columnField
|
||||
}
|
||||
return@FieldFor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼装创建数据表的SQL语句
|
||||
*/
|
||||
private fun getCreateTableSql(): String? {
|
||||
//create table if not exists tb_name(_id integer,name varchar2(20))
|
||||
val sqlCreateTable = StringBuffer()
|
||||
sqlCreateTable.append("create table if not exists ")
|
||||
sqlCreateTable.append("$tableName (")
|
||||
//反射获取所有的数据对象内的成员变量
|
||||
val fields = entityClass!!.declaredFields
|
||||
|
||||
fields.forEachIndexed { index, field ->
|
||||
//字段名称
|
||||
val columnName = field.getAnnotation(DbField::class.java).fieldName
|
||||
//获取成员变量数据类型
|
||||
|
||||
when (val fieldType = field.type) {
|
||||
String::class.java -> {
|
||||
sqlCreateTable.append("$columnName TEXT,")
|
||||
}
|
||||
Integer::class.java -> {
|
||||
sqlCreateTable.append("$columnName INTEGER,")
|
||||
}
|
||||
Long::class.java -> {
|
||||
sqlCreateTable.append("$columnName BIGINT,")
|
||||
}
|
||||
Double::class.java -> {
|
||||
sqlCreateTable.append("$columnName DOUBLE,")
|
||||
}
|
||||
ByteArray::class.java -> {
|
||||
sqlCreateTable.append("$columnName BLOB,")
|
||||
}
|
||||
else -> {
|
||||
//未知类型
|
||||
throw UnsupportedOperationException("未定义的数据类型:fieldName= $columnName fieldType= $fieldType")
|
||||
}
|
||||
}
|
||||
|
||||
if (index == fields.size - 1) {
|
||||
if (sqlCreateTable.endsWith(","))
|
||||
sqlCreateTable.deleteCharAt(sqlCreateTable.length - 1)
|
||||
}
|
||||
}
|
||||
sqlCreateTable.append(")")
|
||||
|
||||
return sqlCreateTable.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入数据
|
||||
*/
|
||||
override fun insert(entity: T): Long {
|
||||
//1、准备好ContentValues中的数据
|
||||
//2、设置插入的内容
|
||||
val values: ContentValues = getContentValuesForInsert(entity)
|
||||
//3、执行插入
|
||||
return if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) {
|
||||
sqLiteDatabase!!.insert(tableName, null, values)
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
override fun delete(where: T): Int {
|
||||
val condition = Condition(getContentValuesForQuery(where))
|
||||
|
||||
return if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) {
|
||||
//受影响行数
|
||||
sqLiteDatabase!!
|
||||
.delete(
|
||||
tableName,
|
||||
condition.getWhereCause(),
|
||||
condition.getWhereArgs()
|
||||
)
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据
|
||||
*/
|
||||
override fun update(where: T, newEntity: T): Int {
|
||||
val condition = Condition(getContentValuesForQuery(where))
|
||||
|
||||
return if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) {
|
||||
//受影响行数
|
||||
sqLiteDatabase!!
|
||||
.update(
|
||||
tableName,
|
||||
getContentValuesForInsert(newEntity),
|
||||
condition.getWhereCause(),
|
||||
condition.getWhereArgs()
|
||||
)
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据
|
||||
* @param where 查询条件对象,同时也用来初始化对象使用
|
||||
*/
|
||||
override fun query(where: T): MutableList<T> {
|
||||
return query(where, null, null, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据
|
||||
* @param where 查询条件对象
|
||||
* @param orderBy 排序规则
|
||||
* @param startIndex 开始的位置
|
||||
* @param limit 限制查询得到的数据个数
|
||||
*/
|
||||
fun query(where: T, orderBy: String?, startIndex: Int?, limit: Int?): MutableList<T> {
|
||||
//拼接分页语句
|
||||
var limitString: String? = null
|
||||
if (startIndex != null && limit != null) {
|
||||
limitString = "$startIndex,$limit"
|
||||
}
|
||||
|
||||
val condition = Condition(getContentValuesForQuery(where))
|
||||
|
||||
var cursor: Cursor? = null
|
||||
|
||||
//定义查询结果
|
||||
val result = mutableListOf<T>()
|
||||
if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) {
|
||||
try {
|
||||
//查询数据库
|
||||
cursor = sqLiteDatabase!!
|
||||
.query(
|
||||
tableName,
|
||||
null,
|
||||
condition.getWhereCause(),
|
||||
condition.getWhereArgs(),
|
||||
null,
|
||||
null,
|
||||
orderBy,
|
||||
limitString
|
||||
)
|
||||
//将查到结果添加到返回集合中
|
||||
result.addAll(getQueryResult(cursor, where))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询使用的ContentValues
|
||||
*/
|
||||
private fun getContentValuesForQuery(entity: T): ContentValues {
|
||||
val contentValues = ContentValues()
|
||||
try {
|
||||
cacheField!!.forEach {
|
||||
if (it.value.get(entity) == null) {
|
||||
return@forEach
|
||||
}
|
||||
contentValues.put(it.key, it.value.get(entity).toString())
|
||||
}
|
||||
} catch (e: IllegalAccessError) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return contentValues
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件拼接
|
||||
*/
|
||||
class Condition(whereContent: ContentValues) {
|
||||
/**
|
||||
* 条件拼接
|
||||
* _id=?&&name=?
|
||||
*/
|
||||
private var whereCause: String? = null
|
||||
|
||||
private var whereArgs: Array<String>? = null
|
||||
|
||||
//根据传入的contentValues转换成查询条件
|
||||
init {
|
||||
//记录后面填充到查询语句“?”上的数据参数
|
||||
val argList = mutableListOf<String>()
|
||||
//拼接查询语句
|
||||
val whereCaseSb = StringBuilder()
|
||||
|
||||
/**
|
||||
* 是为了链接下面的查询条件条件,也或者是替换没有查询条件的语句。
|
||||
* 比如:要把检索条件作为一个参数传递给SQL,
|
||||
* 那么,当这个检索语句不存在的话就可以给它赋值为1=1.
|
||||
* 这样就避免了SQL出错,也就可以把加条件的SQL和不加条件的SQL合二为一。
|
||||
*/
|
||||
whereCaseSb.append(" 1=1 ")
|
||||
|
||||
val keys = whereContent.keySet()
|
||||
val iterator = keys.iterator()
|
||||
|
||||
//因为使用了“1=1”,所以即便是这里没有任何数据拼接,也是可以正常
|
||||
while (iterator.hasNext()) {
|
||||
val key = iterator.next() as String
|
||||
val valueObject = whereContent.get(key)
|
||||
if (valueObject != null) {
|
||||
val value = valueObject as String
|
||||
//拼接查询条件语句
|
||||
//1:1 and _id=? and name=?
|
||||
whereCaseSb.append(" and $key =?")
|
||||
|
||||
//记录?对应的value
|
||||
argList.add(value)
|
||||
}
|
||||
}
|
||||
//集合转成数组
|
||||
this.whereArgs = argList.toTypedArray()
|
||||
this.whereCause = whereCaseSb.toString()
|
||||
}
|
||||
|
||||
fun getWhereCause(): String {
|
||||
return this.whereCause!!
|
||||
}
|
||||
|
||||
fun getWhereArgs(): Array<String> {
|
||||
return this.whereArgs!!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询db结果
|
||||
*/
|
||||
private fun getQueryResult(cursor: Cursor, where: T): MutableList<T> {
|
||||
//定义查询结果
|
||||
val result = mutableListOf<T>()
|
||||
//Cursor从头读到尾
|
||||
//游标从头读到尾
|
||||
cursor.moveToFirst()
|
||||
//移动游标获取下一行数据
|
||||
while (!cursor.isAfterLast) {
|
||||
//通过反射构建一个查询结果对象
|
||||
val item = where.javaClass.newInstance()
|
||||
|
||||
//拿到缓存的当前数据对象的成员变量与数据库的键值关系
|
||||
val fieldIterator = cacheField!!.entries.iterator()
|
||||
fieldIterator.forEach IteratorFor@{
|
||||
//获取数据库字段名称
|
||||
val columnName = it.key
|
||||
//数据库字段名对应的数据对象的成员变量
|
||||
val field = it.value
|
||||
//获取指定列名对应的索引
|
||||
val columnIndex = cursor.getColumnIndex(columnName)
|
||||
//获取成员变量数据类型
|
||||
val fieldType = field.type
|
||||
|
||||
if (columnIndex != -1) {
|
||||
when (fieldType) {
|
||||
String::class.java -> {
|
||||
field.set(item, cursor.getString(columnIndex))
|
||||
}
|
||||
Integer::class.java -> {
|
||||
field.set(item, cursor.getInt(columnIndex))
|
||||
}
|
||||
Long::class.java -> {
|
||||
field.set(item, cursor.getLong(columnIndex))
|
||||
}
|
||||
Double::class.java -> {
|
||||
field.set(item, cursor.getDouble(columnIndex))
|
||||
}
|
||||
ByteArray::class.java -> {
|
||||
field.set(item, cursor.getBlob(columnIndex))
|
||||
}
|
||||
else -> {
|
||||
//未知类型
|
||||
throw UnsupportedOperationException("未定义的数据类型:columnName= $columnName fieldType= $fieldType")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//添加到结果集
|
||||
result.add(item)
|
||||
//移动到下一个位置
|
||||
cursor.moveToNext()
|
||||
}
|
||||
cursor.close()
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插入使用的ContentValues
|
||||
*/
|
||||
private fun getContentValuesForInsert(entity: T): ContentValues {
|
||||
val contentValues = ContentValues()
|
||||
|
||||
val fieldIterator = cacheField!!.entries.iterator()
|
||||
|
||||
fieldIterator.forEach IteratorFor@{
|
||||
try {
|
||||
//获取变量的值
|
||||
val valueObject = it.value.get(entity) ?: return@IteratorFor
|
||||
//获取列名
|
||||
val columnName = it.key
|
||||
//获取成员变量数据类型
|
||||
val fieldType = it.value.type
|
||||
when (fieldType) {
|
||||
String::class.java -> {
|
||||
contentValues.put(columnName, valueObject as String)
|
||||
}
|
||||
Integer::class.java -> {
|
||||
contentValues.put(columnName, valueObject as Int)
|
||||
}
|
||||
Long::class.java -> {
|
||||
contentValues.put(columnName, valueObject as Long)
|
||||
}
|
||||
Double::class.java -> {
|
||||
contentValues.put(columnName, valueObject as Double)
|
||||
}
|
||||
ByteArray::class.java -> {
|
||||
contentValues.put(columnName, valueObject as ByteArray)
|
||||
}
|
||||
else -> {
|
||||
//未知类型
|
||||
throw UnsupportedOperationException("未定义的数据类型:columnName= $columnName fieldType= $fieldType")
|
||||
}
|
||||
}
|
||||
} catch (e: IllegalArgumentException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
return contentValues
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.mogo.utils.sqlite
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import com.mogo.utils.sqlite.annotation.DbDatabase
|
||||
import com.mogo.utils.sqlite.proxy.BaseDaoProxyLog
|
||||
|
||||
|
||||
/**
|
||||
* <p>数据库处理工厂</p>
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
open class BaseDaoFactory {
|
||||
|
||||
//默认数据库名称
|
||||
private var dbName = "AppSQLite.db"
|
||||
|
||||
companion object {
|
||||
//单利工厂
|
||||
private var baseDaoFactory: BaseDaoFactory? = null
|
||||
|
||||
//数据库存储路径
|
||||
private lateinit var sqLiteDatabasePath: String
|
||||
|
||||
//数据库操作类
|
||||
private var sqLiteDatabase: SQLiteDatabase? = null
|
||||
|
||||
fun getInstance(): BaseDaoFactory {
|
||||
if (baseDaoFactory == null) {
|
||||
synchronized(BaseDaoFactory::class.java) {
|
||||
if (baseDaoFactory == null) {
|
||||
baseDaoFactory = BaseDaoFactory()
|
||||
}
|
||||
}
|
||||
}
|
||||
return baseDaoFactory!!
|
||||
}
|
||||
}
|
||||
|
||||
//获取数据库操作对象
|
||||
fun <T : Any> getBaseDao(context: Context, entityClass: Class<T>): IBaseDao<T>? {
|
||||
var baseDao: IBaseDao<T>? = null
|
||||
|
||||
try {
|
||||
//获取数据库名称,如果没有设置则使用默认名称
|
||||
val dbDatabase = entityClass.getAnnotation(DbDatabase::class.java)
|
||||
if (dbDatabase != null) {
|
||||
dbName = dbDatabase.dbName
|
||||
}
|
||||
//openOrCreateDatabase 如果不存在则先创建再打开数据库,如果存在则直接打开。
|
||||
sqLiteDatabasePath =
|
||||
"${context.getDir("database", Context.MODE_APPEND).path}/$dbName"
|
||||
sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(sqLiteDatabasePath, null)
|
||||
|
||||
// 这里为了演示,添加了日志工具的叠加使用,根据需要可以自己修改
|
||||
// baseDao = BaseDaoProxyShow().bind(BaseDaoProxyLog().bind(BaseDao<T>())) as IBaseDao<T>
|
||||
baseDao = BaseDaoProxyLog().bind(BaseDao<T>()) as IBaseDao<T>
|
||||
|
||||
baseDao.init(sqLiteDatabase!!, entityClass)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return baseDao
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭数据库
|
||||
*/
|
||||
fun closeDatabase() {
|
||||
sqLiteDatabase?.close()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.mogo.utils.sqlite
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* <p>操作SQLite数据库的顶层接口</p>
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
interface IBaseDao<T> {
|
||||
/**
|
||||
* 初始化数据库连接
|
||||
*/
|
||||
fun init(sqLiteDatabase: SQLiteDatabase, entityClass: Class<T>): Boolean
|
||||
|
||||
/**
|
||||
* 将 [entity] 进行数据插入
|
||||
*/
|
||||
fun insert(entity: T): Long
|
||||
|
||||
/**
|
||||
* 根据条件 [where] 进行数据删除
|
||||
*/
|
||||
fun delete(where: T): Int
|
||||
|
||||
/**
|
||||
* 根据条件 [where] 进行数据更新,如果[where]==null 则代表删除所有数据
|
||||
*/
|
||||
fun update(where: T, newEntity: T): Int
|
||||
|
||||
/**
|
||||
* 根据条件 [where] 进行数据查询,如果[where]==null 则代表查询所有数据
|
||||
*/
|
||||
fun query(where: T): MutableList<T>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.mogo.utils.sqlite.annotation
|
||||
|
||||
|
||||
/**
|
||||
* <p>添加在要操作的数据对象名上面,用来设置数据库名称</p>
|
||||
*
|
||||
* /**
|
||||
* * @DbDatabase("AppSQLite.db")
|
||||
* * class UserEntity {}
|
||||
* */
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class DbDatabase(val dbName: String)
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.mogo.utils.sqlite.annotation
|
||||
|
||||
|
||||
/**
|
||||
* <p>添加在要处理的数据对象的字段之上,用来设置数据表的字段名称</p>
|
||||
* /**
|
||||
* *@DbTable("tb_user")
|
||||
* *class UserEntity {
|
||||
* * @DbField("_id")
|
||||
* * var id: Int = 0
|
||||
* * @DbField("name")
|
||||
* * var name: String? = null
|
||||
* * @DbField("password")
|
||||
* * var password: String? = null
|
||||
* *}
|
||||
* */
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.FIELD)
|
||||
annotation class DbField(val fieldName: String)
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.mogo.utils.sqlite.annotation
|
||||
|
||||
|
||||
/**
|
||||
* <p>添加在要操作的数据对象名上面,用来设置数据表名称</p>
|
||||
*
|
||||
* /**
|
||||
* * @DbTable("tb_user")
|
||||
* * class UserEntity {}
|
||||
* */
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class DbTable(val tableName: String)
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.mogo.utils.sqlite.proxy
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.util.Log
|
||||
import com.mogo.utils.sqlite.IBaseDao
|
||||
|
||||
/**
|
||||
* <p>静态代理数据库操作类,用来记录日志</P>
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
class BaseDaoProxy<T>(var iBaseDao: IBaseDao<T>) : IBaseDao<T> by iBaseDao {
|
||||
override fun init(sqLiteDatabase: SQLiteDatabase, entityClass: Class<T>): Boolean {
|
||||
Log.i("数据库代理", "初始化数据库连接……")
|
||||
val isInitSuccess = iBaseDao.init(sqLiteDatabase, entityClass)
|
||||
if (isInitSuccess) {
|
||||
Log.i("数据库代理", "数据库连接成功……")
|
||||
} else {
|
||||
Log.e("数据库代理", "数据库连接失败……")
|
||||
}
|
||||
return isInitSuccess
|
||||
}
|
||||
|
||||
override fun insert(entity: T): Long {
|
||||
Log.i("数据库代理", "开始插入数据……")
|
||||
val result = iBaseDao.insert(entity)
|
||||
Log.i("数据库代理", "插入数据索引位置> $result <……")
|
||||
return result
|
||||
}
|
||||
|
||||
override fun delete(where: T): Int {
|
||||
Log.i("数据库代理", "开始删除数据……")
|
||||
val result = iBaseDao.delete(where)
|
||||
Log.i("数据库代理", "删除了> $result <条数据……")
|
||||
return result
|
||||
}
|
||||
|
||||
override fun update(where: T, newEntity: T): Int {
|
||||
Log.i("数据库代理", "开始更新数据……")
|
||||
val result = iBaseDao.update(where, newEntity)
|
||||
Log.i("数据库代理", "更新了> $result <条数据……")
|
||||
return result
|
||||
}
|
||||
|
||||
override fun query(where: T): MutableList<T> {
|
||||
Log.i("数据库代理", "开始查询数据……")
|
||||
val result = iBaseDao.query(where)
|
||||
Log.i("数据库代理", "查询到> ${result.size} <条数据……")
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.mogo.utils.sqlite.proxy
|
||||
|
||||
import android.util.Log
|
||||
import java.lang.reflect.InvocationHandler
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
/**
|
||||
* 使用java实现动态代理数据库操作类加入日志功能
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
|
||||
class BaseDaoProxyLog : InvocationHandler {
|
||||
|
||||
private var target: Any? = null
|
||||
|
||||
/**
|
||||
* 绑定委托对象并返回一个【代理占位】
|
||||
*
|
||||
* @param target 真实对象
|
||||
* @return 代理对象【占位】
|
||||
*/
|
||||
fun bind(target: Any): Any {
|
||||
this.target = target
|
||||
//取得代理对象
|
||||
return Proxy.newProxyInstance(
|
||||
target.javaClass.classLoader,
|
||||
target.javaClass.interfaces, this
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 同过代理对象调用方法首先进入这个方法.
|
||||
*
|
||||
* @param proxy --代理对象
|
||||
* @param method -- 方法,被调用方法.
|
||||
* @param args -- 方法的参数
|
||||
*/
|
||||
@Throws(Throwable::class)
|
||||
override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any? {
|
||||
var result: Any? = null
|
||||
//反射方法前调用
|
||||
Log.i("数据库代理", "当前执行>>${method.name}")
|
||||
//反射执行方法 相当于调用target.sayHelllo;
|
||||
result = method.invoke(target, *args)
|
||||
//反射方法后调用.
|
||||
Log.i("数据库代理", "执行结果>>$result")
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.mogo.utils.sqlite.proxy
|
||||
|
||||
import android.util.Log
|
||||
import java.lang.reflect.InvocationHandler
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
/**
|
||||
* 使用java实现动态代理数据库操作类,加入更多额外的功能,来测试代理类的叠加功能
|
||||
* Created by donghongyu on 2019/9/6.
|
||||
*/
|
||||
class BaseDaoProxyShow : InvocationHandler {
|
||||
|
||||
private var target: Any? = null
|
||||
|
||||
/**
|
||||
* 绑定委托对象并返回一个【代理占位】
|
||||
*
|
||||
* @param target 真实对象
|
||||
* @return 代理对象【占位】
|
||||
*/
|
||||
fun bind(target: Any): Any {
|
||||
this.target = target
|
||||
//取得代理对象
|
||||
return Proxy.newProxyInstance(
|
||||
target.javaClass.classLoader,
|
||||
target.javaClass.interfaces, this
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 同过代理对象调用方法首先进入这个方法.
|
||||
*
|
||||
* @param proxy --代理对象
|
||||
* @param method -- 方法,被调用方法.
|
||||
* @param args -- 方法的参数
|
||||
*/
|
||||
@Throws(Throwable::class)
|
||||
override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any? {
|
||||
var result: Any? = null
|
||||
//反射方法前调用
|
||||
Log.i("数据库代理", "显示执行>>${method.name}")
|
||||
//反射执行方法 相当于调用target.sayHelllo;
|
||||
result = method.invoke(target, *args)
|
||||
//反射方法后调用.
|
||||
Log.i("数据库代理", "执行结果>>$result")
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -52,19 +52,22 @@ dependencies {
|
||||
compileOnly rootProject.ext.dependencies.androidxccorektx
|
||||
compileOnly rootProject.ext.dependencies.androidxrecyclerview
|
||||
|
||||
compileOnly rootProject.ext.dependencies.mogomap
|
||||
compileOnly rootProject.ext.dependencies.mogoutils
|
||||
compileOnly rootProject.ext.dependencies.mogocommons
|
||||
compileOnly rootProject.ext.dependencies.mogoservice
|
||||
compileOnly rootProject.ext.dependencies.mogoserviceapi
|
||||
compileOnly rootProject.ext.dependencies.modulecommon
|
||||
compileOnly rootProject.ext.dependencies.moduleservice
|
||||
compileOnly rootProject.ext.dependencies.androidxappcompat
|
||||
compileOnly rootProject.ext.dependencies.androidxconstraintlayout
|
||||
compileOnly rootProject.ext.dependencies.arouter
|
||||
compileOnly rootProject.ext.dependencies.carcallprovider
|
||||
compileOnly rootProject.ext.dependencies.carcall
|
||||
|
||||
implementation project(':foudations:mogo-utils')
|
||||
implementation project(':foudations:mogo-commons')
|
||||
implementation project(':modules:mogo-module-map')
|
||||
implementation project(':modules:mogo-module-common')
|
||||
implementation project(':modules:mogo-module-search')
|
||||
implementation project(':modules:mogo-module-service')
|
||||
|
||||
|
||||
annotationProcessor rootProject.ext.dependencies.aroutercompiler
|
||||
|
||||
testImplementation 'junit:junit:4.13'
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.mogo.service.statusmanager.IMogoStatusChangedListener;
|
||||
import com.mogo.service.statusmanager.StatusDescriptor;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
import com.mogo.utils.network.utils.GsonUtil;
|
||||
import com.mogo.utils.sqlite.IBaseDao;
|
||||
import com.mogo.utils.storage.SharedPrefsMgr;
|
||||
|
||||
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
|
||||
|
||||
Reference in New Issue
Block a user