介绍
LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式,将平时开发时最常用的一些数据库功能进行了封装,使得开发者不用编写一行SQL语句就可以完成各种建表、増删改查的操作。
LitePal开源项目的GitHub
说明
据LitePal数据类型支持,可进行对象关系映射的数据类型共8种,int、short、long、float、double、boolean、String和Date。只要声明成这8种数据类型的字段都会被自动映射到数据库表中,不需任何额外配置。
经过测试,LitePal还可以存储byte[]、List、List。
使用示例
1.添加依赖
Java版本:
dependencies {
implementation 'org.litepal.android:kotlin:3.0.0'
}
Kotlin版本:
dependencies {
implementation 'org.litepal.android:kotlin:3.0.0'
}
2.混淆
# Litepal
-keep class org.litepal.** {*;}
-keep class * extends org.litepal.crud.DataSupport {*;}
-keep class * extends org.litepal.crud.LitePalSupport {*;}
3.创建表
在LitePal中,一个数据库的每一张表对应着一个类,这个类只需要继承自LitePalSupport类中就会有save() 和 delete()两个方法,分别代表着保存(更新)和删除。
public class UserInfo extends LitePalSupport {
@SerializedName(value = "id")
private long userId;
private String username;
@Column(defaultValue = "0123456789")
private String phone;
@Column(ignore = true)
private String city;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
3.1 所有的column注解
用@column在实体类中为属性注解可以在创建数据库时为表中的字段添加字段的约束,所以这是一个非常重要的知识点,认识所有的column注解很有必要。
public @interface Column {
/**
* 为列设置可为空的约束
*/
boolean nullable() default true;
/**
* 为列设置唯一约束
*/
boolean unique() default false;
/**
* 不管列类型是什么,都为列设置带字符串类型的默认值
*/
String defaultValue() default "";
/**
* 忽略将此字段映射到列,既数据库不保存此项
*/
boolean ignore() default false;
}
3.2 主键
由于LitePal的主键是自动生成的,不管一个实体类对象有没有设置id字段,数据库的表中都会创建一个id的主键。
遇到问题: 在处理后台返回的json数据,使用Gson解析json成对象时默认的是将json里对应字段的值解析到java对象里对应字段的属性里面。当后台返回的数据中也存在字段名为id时,将解析后的数据直接保存进数据库后,我们通过getId()获取到的id是数据自增的主键id,而不是后台的字段名id。
解决方法:
为了解决上述的问题,有两种方案:一、让后台更改字段名;二、通过@SerializedName字段。
@SerializedName(value = "id")
private long userId;
@SerializedName注解来将对象里的属性名userId跟json里字段名id匹配起来。
4.配置litepal.xml
LitePal在使用的时候,需要配置一个litepal.xml文件放在安卓的assets目录中。如果没有这个文件夹,点击你的项目app,右键new->Folder->Assets Folder
有了这个文件夹后,选中右键新建一个File,注意不要选择xml,命名为litepal.xml即可。
litepal.xml
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<!--数据库名-->
<dbname value="Lock" />
<!--数据库版本号-->
<version value="1" />
<!--表-->
<list>
<mapping class="com.fenda.slock.data.entity.UserInfo" />
<mapping class="com.fenda.slock.data.entity.LockDevice" />
</list>
</litepal>
这里要注意,如果项目更新有对数据库增加、修改或删除表以及对表中的字段进行修改需要对版本号加1,不然新的数据库不会生效并有可能闪退。
5.配置LitePalApplication
(1)在AndroidManifest.xml 中配置,用这种方式的话,所有的数据库操作就不用传Context了
<manifest>
<application
android:name="org.litepal.LitePalApplication"
...
>
...
</application>
</manifest>
(2)如果你的应用程序已经有Application 了。则可以让其继承LitePalApplication 。如果继承的是Application。则可以在onCreate 方法里面加入LitePal.initialize(this)
public class MyOwnApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LitePal.initialize(this);
}
...
}
6.数据库的增删查改
6.1 增
UserInfo userInfo = new UserInfo();
userInfo.setUserId = 1;
userInfo.setUsername = "小李"
userInfo.setPhone = "12345678900"
userInfo.save();
save会返回 boolean 值,true表示成功,false表示失败;
List<UserInfo> userInfoList;
...
LitePal.saveAll(userInfoList);
LitePal提供了一个saveAll()方法,专门用于存储集合数据的;
6.2 改
(1)把UserInfo表中主键(id)为2的记录的手机号改成“96385274100”
UserInfo userInfo = new UserInfo();
userInfo.setPhone("96385274100");
updateNews.update(2);
或者
ContentValues values = new ContentValues();
values.put("phone", "96385274100");
LitePal.update(UserInfo.class, values, 2);
(2)把UserInfo表中手机号为“12345678900”且名字为“小李”的所有手机号改成“96385274100”
UserInfo userInfo = new UserInfo();
userInfo.setPhone("96385274100");
userInfo.updateAll("phone = ? and name = ?", "12345678900","小李");
或者
ContentValues values = new ContentValues();
values.put("phone", "96385274100");
LitePal.updateAll(UserInfo.class, values, "phone = ? and name = ?", "12345678900","小李");
(3)把UserInfo表中的所有手机号改成“96385274100”
ContentValues values = new ContentValues();
values.put("phone", "96385274100");
LitePal.updateAll(UserInfo.class, values);
(4)把某一条数据修改成默认值,比如说我们想要把UserInfo表中所有城市改成默认值
UserInfo userInfo = new UserInfo();
userInfo.setToDefault("city");
userInfo.updateAll();
(5)如果我们要保存某一项数据,但不知道该数据是否存在,如果不存在就保存,存在就更新数据。可以使用saveOrUpdate。
UserInfo userInfo = new UserInfo();
userInfo.setUserId = 1;
userInfo.setUsername = "小李"
userInfo.setPhone = "12345678900"
userInfo.saveOrUpdate("userId = ?", "5");
6.3 删
(1)删除UserInfo表中主键(id)为2的记录
LitePal.delete(UserInfo.class, 2);
(2)指定条件删除,如删除名字为“小李”的记录
LitePal.deleteAll(UserInfo.class, "name = ?","小李");
(3)删除表中所有的数据
LitePal.deleteAll(UserInfo.class);
6.4 查
(1)获取UserInfo表中的第一条数据
UserInfo userInfo = LitePal.findFirst(UserInfo.class);
(2)获取UserInfo表中的最后一条数据
UserInfo userInfo = LitePal.findLast(UserInfo.class);
(3)查询UserInfo表中主键(id)为2的记录
UserInfo userInfo = LitePal.find(UserInfo.class,2);
(4)查询UserInfo表中主键(id)为1、3、5、7的记录
List<UserInfo> userInfoList = LitePal.findAll(UserInfo.class, 1, 3, 5, 7);
(5)查询UserInfo表中所有的记录
List<UserInfo> userInfoList = LitePal.findAll(UserInfo.class);
(6)条件查询
查询所有符合条件的
List<UserInfo> userInfoList = LitePal.where("name = ?", "小李").find(UserInfo.class);
查询符合条件的最后一条数据
UserInfo userInfo = LitePal.where("name = ?", "小李").findLast(UserInfo.class);
查询符合条件的某一项数据
List<UserInfo> userInfoList = LitePal.select("phone")
.where("name = ?", "小李")
.find(UserInfo.class);
查询符合条件的数据并排序,asc表示正序排序,desc表示倒序排序
List<UserInfo> userInfoList = LitePal.select("phone")
.where("name = ?", "小李")
.order("userId desc")
.find(UserInfo.class);
查询符合条件的数据并排序,取排序的前10条
List<UserInfo> userInfoList = LitePal.select("phone")
.where("name = ?", "小李")
.order("userId desc")
.limit(10)
.find(UserInfo.class);
刚才我们查询到的是所有匹配条件的前10条数据,那么现在我想对数据进行分页展示,翻到第二页时,展示第11到第20条数据,只需要添加偏移量
List<UserInfo> userInfoList = LitePal.select("phone")
.where("name = ?", "小李")
.order("userId desc")
.limit(10)
.offset(10)
.find(UserInfo.class);
7.聚合函数
LitePal中一共提供了count()、sum()、average()、max()和min()这五种聚合函数,基本上已经将SQL语句当中最常用的几种聚合函数都覆盖了。
7.1 count()
count()方法主要是用于统计行数的
int result = LitePal.where("name = ?", "小华").count(UserInfo.class);
7.2 sum()
sum()方法主要是用于对结果进行求合的
int result = LitePal.sum(UserInfo.class, "userId", int.class);
第一个参数很简单,还是传入的Class,用于指定去统计哪张表当中的数据。第二个参数是列名,表示我们希望对哪一个列中的数据进行求合。第三个参数用于指定结果的类型,这里我们指定成int型,因此返回结果也是int型。
需要注意的是,sum()方法只能对具有运算能力的列进行求合,比如说整型列或者浮点型列,如果你传入一个字符串类型的列去求合,肯定是得不到任何结果的,这时只会返回一个0作为结果。
7.3 average()
average()方法主要是用于统计平均数的
double result = LitePal.average(UserInfo.class, "userId");
7.4 max()
max()方法主要用于求出某个列中最大的数值
int result = LitePal.max(UserInfo.class, "userId", int.class);
7.5 min()
min()方法主要用于求出某个列中最小的数值
int result = LitePal.min(UserInfo.class, "userId", int.class);