KopDB 框架学习2——源码分析

本文深入分析KopDB框架的源码,重点探讨BaseModel.java和DatabaseManager.java的核心功能,包括初始化、查询、插入、更新、替换和删除等数据库操作。KopDB采用ORM模式,简化数据库交互,通过反射机制实现对象与表的映射。
摘要由CSDN通过智能技术生成

我的博客:http://mrfufufu.github.io/

上次我们主要是对 KopDB 框架的使用进行了分析,它是非常简单有用的。这次主要是对它的源码进行分析,进一步的来了解它的真面目。

点击这里去往 “KopDB 框架学习1——使用”

因为 KopDB 采用的是对象关系映射(ORM)模式,即我们使用的编程语言是面向对象语言,而我们使用的数据库则是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射了。

使用 ORM 模式,主要是因为我们平时多用面向对象编程,只有少部分人才会比较精通关系型数据库。通过这种模式,可以让我们不考虑 SQL 语言的具体实现,从而专注于业务实现。

根据 ORM 模式的理念,我们每张表都应该对应一个模型,即,如果我们想要建一张 Person 表,就应该有一个 Person 类。

类关系图

MrFuDB

核心类功能的介绍:

1. BaseModel.java

所有的模型都应继承这个类,这个类的主要有两个方法:

getContentValues(): ContentValues:为将要进行的数据库操作获取表的字段和对应的值。方法是将对应的 model 通过反射的形式获取到它的列名和值,返回的是 ContentValues 对象。

getModels(Cursor curor):List<T>: 为查询数据库操作以后得到的数据进行解析,返回对应的 model 类型 的List。方法是将查询完数据库以后会得到一个 Cursor,所有的查询操作得到值都通过这个变量返回,对这个 cursor 中的对应列的值映射到对应的 model 中去。

2. DatabaseManager.java

最主要用到的类就是DatabaseManager类的,通过这类,我们完全了所有的数据库的操作,包括建表,增删查改等操作。注意,需要通过单例得到它的实例,主要方法有:

a. 初始化操作
initDataBase(Context context, String dbName, int version, List<Class<?>> models)

数据库的初始化相关的操作,dbName为数据库的名称,version 就是数据库的版本,models 为需要映射到数据库中去的 model,具体映射方法我们在DatabaseTools.java类中来讲。

b. 查询操作
select(Class<T> claz, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

直接通过 claz 拿到数据库名字,根据 SQLiteDatabase 的实例直接去进行 query 的操作,query 的到 Cursor 的对象,所有的数据都在这里面,然后调用BaseModel.java中的getModels(Cursor curor)方法得到 List 数据,即完成。

c. 插入操作

insert 插入操作,有4个重载方法,这里只分析

insert(Class<T> claz, T t, DBOperateAsyncListener listener)

方法的实现,其他的大同小异。先是创建了 DBMsgObject 对象,用来作为 Message 的 obj,所有的操作数据库操作都会到对应的 handle 去进行。具体 insert 方法如下:

public <T extends BaseModel> void insert(Class<T> claz, T t, DBOperateAsyncListener listener) {
      
    if (claz != null && t != null) {
        DBMsgObject<T> msgObj = new DBMsgObject<T>();//创建DBMsgObject 对象,作为Message 的 obj 
        msgObj.claz = claz;
        ContentValues contentValues = null;
        try {
            contentValues = t.getContentValues();//拿到 BaseModel 的 ContentValues
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (contentValues != null) {
            //ContentCondition 主要为插入数据库的条件,值
            List<DBMsgObject.ContentCondition<T>> contentConditionList = new ArrayList<DBMsgObject.ContentCondition<T>>();
            DBMsgObject.ContentCondition<T> condition = new DBMsgObject.ContentCondition<T>();
            condition.model = t;//对应的 model
            condition.contentValues = contentValues;//要插入的值(键值对的形式,key 就是列名)
            contentConditionList.add(condition);//这里是单个 model 所有只需要 add 一次
            msgObj.contentConditionList = contentConditionList;
            msgObj.listener = listener;//对应的监听
            Message msg = new Message();
            msg.what = DatabaseOptionType.OPTION_INSERT.VALUE;//消息类型
            msg.obj = msgObj;
            handler.sendMessage(msg);//在 handler 中处理
        }
    }
}

如果是如下重载方法的话,只是对 models 多了一个 for 循环,具体代码就不再给出

insert(Class<T> claz, List<T> models, DBOperateAsyncListener listener)
d. 同步插入操作

syncInsert 同步插入操作,即在当前线程中去操作,而不是在子线程进行。除了syncInsert,其他所有的操作都是在 Handler 中完成的。代码如下:

public  <T extends BaseModel> long syncInsert( Class<T> claz, T value,boolean bNeedNotify) {
      
    if(appAppDatabase == null){
        return -
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值