目录

  • Room实现数据统一管理-Repo
    • 原理
      • Room
      • 反射
    • 具体实现
      • Repo(Kotlin)
      • BaseRepo(Kotlin)
      • BaseDao(Java)
      • BaseEntity(Java)
    • 准备工作(Kotlin)
      • 数据类
      • Dao(Kotlin)
      • Repo(Kotlin)
      • Room配置类(Kotlin)
    • 具体使用(Kotlin)
      • 增删改
      • 其他
    • 注意事项

Room实现数据统一管理-Repo

在多module环境中,将数据类单独写在一个module中,只需引入到其他类中即可实现数据库的访问进行增删改查操作
在使用LitePal框架时,发现数据插入等操作极为方便,只需object.insert()即可实现数据写入,但是经常使用是的Room框架并且也挺依赖它可以获取LiveData对象的,所以自己整理了一个统一的管理类Repo,采用工厂模式找到各个Repo类并进行对应的Dao层操作

原理

Room

这里引用Google对Room的解释
处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的使用场景是缓存相关的数据,这样一来,当设备无法访问网络时,用户仍然可以在离线状态下浏览该内容。
Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。具体来说,Room 具有以下优势:

  • 针对 SQL 查询的编译时验证。
  • 可最大限度减少重复和容易出错的样板代码的方便注解。
  • 简化了数据库迁移路径。

出于这些方面的考虑,我们强烈建议您使用 Room,而不是直接使用 SQLite API。

反射

因为该模块是采用工厂模式进行设计,所以各个Repo类的获取均通过反射得到

引用百度百科对反射机制的解释
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

具体实现

Repo(Kotlin)

class Repo {companion object {@SuppressLint("StaticFieldLeak")var context: Context? = null/*** 保存各个Repo类*/private val instance: MutableMap<String, BaseRepo<*>?> = HashMap(3)/*** 在创建application中使用* @param context 上下文对象*/@JvmStaticfun init(context: Context) {Repo.context = context}/*** 获取指定的数据仓库* @param c   类* @param <T> repo* @return T</T> */@JvmStaticfun <T : BaseRepo<*>> get(c: Class<T>): T {if (instance[c.name] == null) {try {val repo = Class.forName(c.name).newInstance() as T// 通过反射获取BaseRepo的init初始化函数try {val initMethod = c.superclass.getDeclaredMethod("init",Context::class.java)initMethod.isAccessible = trueinitMethod.invoke(repo, context)} catch (e: NoSuchMethodException) {e.printStackTrace()} catch (e: InvocationTargetException) {e.targetException.printStackTrace()}instance[c.name] = repo} catch (e: IllegalAccessException) {e.printStackTrace()} catch (e: InstantiationException) {e.printStackTrace()} catch (e: ClassNotFoundException) {e.printStackTrace()}}return instance[c.name] as T!!}}
}

BaseRepo(Kotlin)

open class BaseRepo<D : BaseDao<*>> {/*** 该类对应的dao层对象*/lateinit var dao: D/*** 从Room配置类中获取该dao层对象*/@Synchronizedfun init(context: Context?) {val instance = AbstractDatabase.getInstance(context!!)val entityClass =(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<D>val methods = AbstractDatabase::class.java.methodsfor (method in methods) {if (entityClass.name.contains(method.returnType.name)) {try {dao = method.invoke(instance) as Dbreak} catch (e: IllegalAccessException) {e.printStackTrace()} catch (e: InvocationTargetException) {e.printStackTrace()}}}}
}

BaseDao(Java)

最初使用Kotlin时发现泛型会被转为Any类型,导致方法报错,所以这里使用Java

public interface BaseDao<T extends BaseEntity> {/*** 插入一条数据* @param t 数据源*/@Insertvoid insert(T t);/*** 插入一组数据* @param ts 数据源*/@Insertvoid insert(T... ts);/*** 插入一组数据* @param ts 数据源*/@Insertvoid insert(List<T> ts);/*** 删除一条数据* @param t 数据源*/@Deletevoid delete(T t);/*** 删除一组数据* @param ts 数据源*/@Deletevoid delete(T... ts);/*** 删除一组数据* @param ts 数据源*/@Deletevoid delete(List<T> ts);/*** 更新一条数据* @param t 数据源*/@Updatevoid update(T t);/*** 更新一组数据* @param ts 数据源*/@Updatevoid update(T... ts);/*** 更新一组数据* @param ts 数据源*/@Updatevoid update(List<T> ts);@RawQueryList<T> query(SupportSQLiteQuery sql);@RawQueryint queryInt(SupportSQLiteQuery sql);
}

BaseEntity(Java)

最初使用Kotlin时发现泛型会被转为Any类型,导致方法报错,所以这里使用Java

public class BaseEntity {private String tag = "BaseEntity";@Ignorepublic void insert() {Log.d(tag, "插入数据 " + this.toString());Repo.get(getRepo()).dao.insert(this);}/*** 清空数据通过查询所有数据再删除实现*/@Ignorepublic void clear() {Log.d(tag, "清空数据 " + this.toString());Repo.get(getRepo()).dao.delete(Repo.get(getRepo()).dao.query(new SimpleSQLiteQuery("select * from " + getClass().getSimpleName())));}@Ignorepublic int count() {Log.d(tag, "获取总数 " + this.toString());return Repo.get(getRepo()).dao.queryInt(new SimpleSQLiteQuery("select count(1) from " + getClass().getSimpleName()));}@Ignorepublic void update() {Log.d(tag, "更新数据 " + this.toString());Repo.get(getRepo()).dao.update(this);}@Ignorepublic void delete() {Log.d(tag, "删除数据 " + this.toString());Repo.get(getRepo()).dao.delete(this);}@Ignoreprivate Class getRepo() {Class c = getClass();Class dao = null;try {dao = Class.forName("com.example.entity.repo." + c.getSimpleName() + "Repo");} catch (ClassNotFoundException e) {e.printStackTrace();}return dao;}
}

准备工作(Kotlin)

数据类

/*** 数据类必须继承BaseEntity*/
@Entity
data class Teacher(/*** 唯一id,自增*/@PrimaryKey(autoGenerate = true) val id: Int?,/*** 名字*/@ColumnInfo var name: String = "",/*** 1 男* 0 女*/@ColumnInfo var gender: Int = 0
): BaseEntity() {var tag: String = "Teacher"
}

Dao(Kotlin)

/*** dao层必须继承BaseDao<T>,T为对应数据类* 继承之后即可实现简单的增删改* 查找需要手动编写查询接口,如下方get(string)*/
@Dao
interface TeacherDao: BaseDao<Teacher> {/*** 获取指定姓名的老师* @return LiveData<Teacher>*/@Query("select * from treacher where name=:name")fun get(name: String): LiveData<Teacher>
}

Repo(Kotlin)

class TeacherRepo: BaseRepo<TeacherDao>() {private val map : HashMap<String, LiveData<Teacher>> = hashMapOf()/*** 获取指定姓名的老师* @return LiveData<Teacher>*/fun get(name: String): LiveData<Teacher> {if (map[name] == null) {map[name] = dao.get(name)}return map[name]}
}

Room配置类(Kotlin)

// AbstractDatabase根据自己的需要参考官方文档进行编写
// dao获取方法名必须为get+类名,否则反射可能拿不到该dao对象
abstract fun getTeacherDao(): TeacherDao

具体使用(Kotlin)

增删改

// 要在子线程中使用
val teacher = Teacher(id = 1, name = "张三", gender = 0)
teacher.insert()
teacher.name = "李四"
teacher.update()teacher.delete()Teacher(null).clear()

其他

Repo.get(TeacherRepo::class.java).get("张三").observe(this) {Log.d("Teacher", it.gender.toString());
}

注意事项

  • 在release打包时,添加混淆防止反射找不到类

    // com.example为对应数据module包名
    -keep public class * extends com.example.entity.*
    -keep class com.example.entity.*
    -dontwarn com.example.entity.**
    -keep class com.example.entity.** { *;}
    
  • 在BaseEntity.getRepo()方法中一定要将当中反射的包名修改为自己项目数据module所在类

Room实现数据统一管理-Repo相关推荐

  1. 数据统一管理--企业决策分析之刚需

    一个企业往往具有多个信息系统,系统间相互独立,这就容易造成"信息孤岛"的问题:难以将多个系统的数据汇集,通过数据分析来全面了解公司的运营状况.尤其是对经营跨度大.环节多的公司更是深 ...

  2. 异构数据统一管理推动存储资源盘活

    随着数据量的爆发式增长,许多企业产生数据的量级由原有的TB 级别迅速的提升到 PB 甚至 EB 级别.企业付出成本来存储这些数据的同时自然也想通过挖掘数据信息辅助商业决策,提升管理效率. 大数据经过了 ...

  3. 【ENOVIA的使用】CESA空客集团数据统一管理案例

    案例介绍 1.挑战 CESA需要在全球范围内管理信息,方便整个企业能够查看相关的技术文档.此外,CESA还需要改善CAD数据管理,加强对数字模型的控制,并借助更完善的可视化a工作流来提高产品变更管理效 ...

  4. 安全数据资产统一管理

    安全数据资产 统一管理DataOps,即 Data 和 Operations 的集成,于 2014 年首次提出.Gartner 将 DataOps 定义为"一种协作性的数据管理 实践,专注于 ...

  5. 大快搜索城市运河大数据政务管理平台案例解读

    2019独角兽企业重金招聘Python工程师标准>>> 大快搜索城市运河大数据政务管理平台案例解读 大数据在政务当中的应用对于提高问题解决的效率可谓大有帮助,但政务大数据平台的应用开 ...

  6. 打破数据统一的七大原则

    数据统一在数据分析领域里是个长期的挑战,从事数据分析的从业者希望在数据分析之前,来自不同实体的数据能够在同一个地方呈现出来.数据统一由七部分组成:1.获取数据 2.清洗数据 3.转换数据.4.模式集成 ...

  7. openglshader实现虚拟场景_云桌面,实现办公终端的统一管理与运维

    随着无纸化办公和智能化办公的不断推进,在办公过程中传统PC电脑的缺点愈发凸显.传统电脑的性能会随着使用时长增加而降低,系统维护处理时效性较弱,出现问题需要运维人员到现场解决,费时费力.如果出现更换设备 ...

  8. Vue + webpack 项目配置化、接口请求统一管理

    准备工作 需求由来: 当项目越来越大的时候提高项目运行编译速度.压缩代码体积.项目维护.bug修复......等等成为不得不考虑而且不得不做的问题.  又或者后面其他同事接手你的模块,或者改你的bug ...

  9. 微软发布 Azure 物联网安全中心;阿里巴巴在美申请专利,以实现跨区块链统一管理;Google利用足球训练下一代人工智能……...

    关注并标星星CSDN云计算 极客头条:速递.最新.绝对有料.这里有企业新动.这里有业界要闻,打起十二分精神,紧跟fashion你可以的! 每周三次,打卡即read 更快.更全了解泛云圈精彩news g ...

最新文章

  1. 2020年全球十大突破性技术公布:数字货币等在列
  2. 20分钟+1080显卡,能跑多复杂的模型?
  3. python中的open函数实例_Python中open函数注意点
  4. golang new make 区别
  5. 2021年中国GDP突破110万亿元 同比增长8.1%
  6. 一个插件让你在 Redux 中写 promise 事半功倍
  7. java final域_final域_鲲鹏通用_TaiShan服务器代码移植参考_Java同步原语_华为云
  8. Linux下对文件操作时出现乱码怎么办?
  9. php扩展的xdebug,安装php扩展:Xdebug
  10. python 中BeautifulSoup入门
  11. C#LeetCode刷题之#617-合并二叉树​​​​​​​​​​​​​​(Merge Two Binary Trees)
  12. 干货 | 那些高产的学者都是怎样工作的?
  13. Word中,Mathtype安装遇到的问题及解决方法
  14. Edge浏览器安装Tampermonkey插件
  15. pyecharts绘制条形图、饼图、散点图、词云图、地图等常用图形
  16. Ctrl+Shift+End
  17. 对于初学者的JavaScript 教程
  18. 3U VPX XC7VX690T计算处理板
  19. OSChina 娱乐弹弹弹——程序猿眼中的女人
  20. jcr多久更新一次_JCR-2017更新 | 快来看看你的影响影子吧

热门文章

  1. 判断日期是否是法定节假日或者休息日
  2. 如何像黑客一样思考?荷兰ABN AMRO银行来支招
  3. MYSQL数据库导入错误提示:/*!40101 SET NAMES utf8mb4 */;解决办法!
  4. arpspoof+driftnet+ ARP欺骗简单图片抓取
  5. ioremap和memremap
  6. go语言path包和filepath包的学习与使用
  7. javaWeb-jQuery
  8. 获取系统时间GetSystemTime、GetLocalTime、GetTickTime
  9. Webmin -- Disk and Network Filesystems
  10. 全球10位著名CEO成功之道------胡安·何塞·古铁雷斯