LitePal源码解析——框架结构及关键类说明

#概述
LitePal是GitHub上一款非常火的Android开源库,提供了很多简洁的API,使得我们可以更容易使用SQLite数据库;甚至在不编写任何一句sql语句,也能进行大部分的数据库操作,包括创建、升级数据库及CRUD操作。由于其API十分简洁且有详细的集成说明(Ps:开源库作者编写的关于如何使用LitePal的系列文章),使得我们可以快速将LitePal集成到我们的项目,而且LitePal开源库仍在持续的更新中,目前最新的版本是1.6.0。项目地址戳这里。
#特点
LitePal通过LitePal.xml文件获取数据库的名称、版本号以及表等配置参数,并根据获取的参数来进行数据库的创建/升级。对于数据表的创建、修改和表数据的CRUD操作,均是根据配置文件中配置的模型类的类名和属性名,应用程序在每一次运行后,首次对SQLite数据库进行操作时,都会对配置文件中配置的模型类进行反射拼装成sql语句,然后调用Android原生的数据库操作,完成sql语句的执行。

  • 优点:
  • 配置简单,只有一个配置文件;
  • API简洁,调用方便;
  • 结构清晰,但依赖包却很小;
  • 丰富的API,除了CRUD操作,还提供了多库操作和CRUD的异步操作;
  • 关于开源库的使用,作者提供了系列博文来进行了详细说明,使得集成非常方便。
  • 缺点:
  • 使用反射影响性能;
  • 整个框架很关键的一点是id自增长,这支撑着整个框架的运转,但却使得我们很不方便维护已有的id属性(大部分服务端提供的数据都自带id),需要通过一定的转换,方能正常存储数据。

虽然存在一些缺点,但对于大部分的应用来说,LitePal的缺点并不会表现出来,而LitePal的优点,却能为我们在实际开发工作中节省大量的时间。
#包结构
整个项目从分包、类的命名、再到方法和变量的命名都非常规范。包结构清晰,类和方法见名知意,且注释简单明了。项目结构如下(保留部分关键类):
LitePal源码解析——框架结构及关键类说明_第1张图片
#关键类说明
##全局操作类

  • LitePal:使用LitePal开源库的入口类。通过调用initialize(Context)方法进行初始化之后,方可调用LitePal的其他业务操作方法。通过use(LitePalDB)或者useDefault()方法可进行数据库的切换。
  • LitePalDB:对LitePal数据库配置。它类似于litepal.xml配置,但允许在运行时配置数据库的细节。在支持多数据库功能时,这一点非常重要。
  • LitePalBase:所有的LitePal组件的基类。如果每个组件需要与其他组件互动或者他们有一些相同的逻辑与重复的代码,LitePalBase中可能已经提供了解决方案(方法)。
  • LitePalApplication:主要是对Context实例进行初始化。

##工具类

  • BaseUtility:基础工具类,提供一些基本的通用操作方法。
  • CipherUtil:解密工具,有AES加解密和MD5加密。
  • AESCrypt:加密和解密,使用AES 256位加密,兼容AESCrypt-ObjC 和AESCrypt Ruby。
  • SharedUtil:LitePal使用的偏好文件,存储版本号及大量必要的值。这个工具以键值对的形式帮助LitePal存储关键数据。
  • DBUtility:数据库操作辅助类。

##自定义Exception

  • DatabaseGenerateException:当生成或者更新表时,可能会抛出此异常。
  • DataSupportException:当LitePal使用DataSupport提供的方法处理CRUD操作时,可能会抛出此异常。
  • GlobalException:全局性异常,LitePalApplication中检测Context变量为空时抛出此异常。
  • InvalidAttributesException:当读取litepal.xml文件中定义的属性,并检测所有的值是否有效。如果不属于规则之内的(无效),那么会抛出此异常。
  • ParseConfigurationFileException:默认使用PULL方式解析(DOM和SAX均可)。当解析litepal.xml文件的过程中发生问题,那么将会抛出此异常。

##数据库表管理
###主要操作类

  • org.litepal.tablemanager.LitePalOpenHelper:自定义帮助类,继承自Android原生的SQLiteOpenHelper,在其构造方法中传入了LitePalApplication中初始化的Context成员变量。实现了onCreate()和onUpgrade()两个抽象方法,调用了Generator的create()和upgrade()方法进行数据库表的创建和更新操作。
  • org.litepal.tablemanager.Connector:连接器链接LitePal创建的数据库。通过Connector.getDatabase()方法可以得到SQLiteDatabase实例,以便于后续对数据库的操作。
  • org.litepal.tablemanager.typechange.OrmChange:这是一个抽象的超类,用于将对象字段类型映射到数据库列类型。这个类的目的是定义一个抽象方法,并让所有子类实现它。每个子类处理一种变化,每个子类将实现自己的逻辑来完成各自的业务。
  • org.litepal.tablemanager.Generator:这个类是动态管理数据库的基本类。它是用于创建或更新表的映射类litepal.xml文件。Generator是一个抽象类,它只是读取类属性及属性的类型保存起来作为数据库表的字段名和类型。分析工作委托给子类来做。然后子类可以调用执行方法来完成任务,或者它们可以重写来实现自己的逻辑。Generator的继承关系如下图:
    LitePal源码解析——框架结构及关键类说明_第2张图片
    ###模型类
  • org.litepal.tablemanager.model.TableModel:这是数据库表的模型类。它存储表名和列的HashMap。
  • org.litepal.tablemanager.model.ColumnModel:这是一个用于列的模型类。它存储列名、列类型和列约束信息。
  • org.litepal.tablemanager.model.GenericModel:这是泛型表的模型类。它存储表名、值列名称、值列类型和值ID列名。当泛型集合字段在模型类中声明时,这个类用于创建泛型表。
  • org.litepal.tablemanager.model.AssociationsModel:这是一个表关联模型类。它存储表名、关联表名、保存外键的表名和关联类型。有三种关联类型,分别为one2one,many2one和many2many。如果关联类型是one2one或many2one,外键将在tableholdsforeignkey(关联表)一侧。如果关联关系是many2many,加入的中间表将以两个目标表名称的字母顺序连接来命名,如atable_ctable,注意是根据首字母的顺序。

##CRUD操作

  • org.litepal.crud.ClusterQuery:封装聚合函数,主要方法如下。
  • count():统计
  • sum():求和
  • average():求平均值
  • max():求最大值
  • min():求最小值
  • order():返回排序后的结果
  • findFirst():查询第一条记录
  • findLast():查询最后一条记录
  • limit():限定查询记录数
  • select():直接查询
  • where():约束条件
  • org.litepal.crud.DataHandler:继承于org.litepal.LitePalBase类,这是CRUD组件的基类。所有的CRUD组件中能够共享的普通功能操作都会放在这里。比如获取/设置模型属性值等。继承关系如下:
    LitePal源码解析——框架结构及关键类说明_第3张图片
    子类有以Handler为后缀的业务类,用于处理具体特定的CRUD业务;AssociationsAnalyzer为关联解析器,在正式的数据操作之前,用于分析表的关联关系,以便于拼装sql操作语句。
  • org.litepal.crud.DynamicExecutor:用于动态执行类成员,封装了反射的方法,提供了允许动态调用方法的send()方法和动态访问属性的getField()方法,允许访问私有成员。
  • org.litepal.crud.async.AsyncExecutor:异步线程执行器(执行后台任务),CRUD的异步执行方法。这是一个抽象类,主要是进行线程的创建和启动,具体线程执行的任务将放在子类中执行。继承关系如下:LitePal源码解析——框架结构及关键类说明_第4张图片
  • org.litepal.crud.callback包存放的…Callback接口,用于CRUD异步任务的结果回调。

##注解类

  • org.litepal.annotation.Column:运行时注解,注解的目标为:字段、枚举的常量,用于向列添加约束,对id列无效。
  • org.litepal.annotation.Encrypt:用于标识是否需要对字段对应列存储的数据进行加密的标识。当执行数据保存时,检测到此注解,将会对要存储的数据执行加密操作。

#框架相关知识点

  • sqlite的系统表sqlite_master介绍
  • Java反射机制详解
  • 泛型
  • java泛型(一)、泛型的基本介绍和使用
  • java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题
  • java泛型(三)、通配符的使用
  • Java注解
  • Android三种解析XML方式
  • Android 线程 thread 两种实现方法

你可能感兴趣的:(android数据库)