LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式,将平时开发时最常用的一些数据库功能进行了封装,使得开发者不用编写一行SQL语句就可以完成各种建表、増删改查的操作。并且LitePal很“轻”,jar包大小不到100k,而且近乎零配置,这一点和Hibernate这类的框架有很大区别。目前LitePal的源码已经托管到了GitHub上。
implementation 'org.litepal.android:java:3.0.0'
在app/src/main下新建一个assets文件夹(New->Folder->Assets Folder)
在assets文件夹下创建一个litepal.xml,这个文件非常重要,用于对LitePal的配置。
<!--litepal.xml-->
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="demo"></dbname>
<version value="1"></version>
<cases value="lower"></cases>
<storage value="internal"></storage>
<list></list>
</litepal>
属性说明:
我们需要在AndroidManifest.xml下配置application的值,如果不想一直传递上下文参数。为了简化api,只需在AndroidManifest.xml中配置LitePalApplication,如下所示:
<manifest>
<application
android:name="org.litepal.LitePalApplication"
...
>
...
</application>
</manifest>
如果配置自定义Application,可继承于org.litepal.LitePalApplication(非必须),并在onCreate()方法中调用LitePal.initialize(context)方法。
public class MyApplication extends LitePalApplication{
@Override
public void onCreate() {
super.onCreate();
LitePal.initialize(this);
}
...
}
在建表之前需要了解一下column注解:
用@column在实体类中为属性添加注解,可以在创建数据库时为表中的字段添加约束,例如:
@Column(unique = true, defaultValue = "unknown",nullable = false)
private String userName;
创建一些实体类:
package com.xx.litepaldemo.entity;
import org.litepal.annotation.Column;
import org.litepal.crud.LitePalSupport;
/**
* 用户实体类(相当于创建一个用户信息表)
* 必须要继承自 org.litepal.crud.LitePalSupport
* create by zjn on 2020.4.11
*/
public class User extends LitePalSupport {
@Column(unique = true, defaultValue = "unknown")
private String userName;
@Column(nullable = false)
private String password;
// generated getters and setters.
...
}
package com.xx.litepaldemo.entity;
import org.litepal.annotation.Column;
import org.litepal.crud.LitePalSupport;
/**
* 订单实体类
*/
public class OrderForm extends LitePalSupport {
@Column(unique = true)
private String number;
@Column(nullable = false)
private float money;
// generated getters and setters.
...
}
注意:不管实体类中有没有id这个属性,都会默认在表中创建一个整型(int)的id字段,作为自增的主键。
将类模型添加到litepal.xml中的映射列表中:
<list>
<mapping class="com.xx.litepaldemo.entity.User"/>
<mapping class="com.xx.litepaldemo.entity.OrderForm"/>
</list>
将实体类添加到映射列表后,在下一次操作数据库时将生成这些表。例如,使用以下代码获取SQLiteDatabase后:
SQLiteDatabase db = LitePal.getDatabase();
在LitePal中升级或修改表非常容易。只需修改模型即可:
package com.xx.litepaldemo.entity;
import org.litepal.annotation.Column;
import org.litepal.crud.LitePalSupport;
public class User extends LitePalSupport {
@Column(unique = true)
private String userName;
@Column(nullable = false)
private String password;
private int age;
// generated getters and setters.
...
}
在实体类中添加了age字段,并将userName字段的默认值取消,然后增加 litepal.xml中的版本号:
<version value="2"></version>
LitePal插入数据的方法非常简单,只要实体类继承了LitePalSupport类,那么通过调用自身的sava()方法就可向数据表中插入这条记录。
User user = new User();
user.setUserName("zhangsan");
user.setPassword("password");
user.setAge(20);
user.save();
可以使用LitePal类中的 delete() 方法通过id删除单条记录。
LitePal.delete(User.class, id);
还可以使用LitePal中的 deleteAll() 方法删除多条记录。
LitePal.deleteAll(OrderForm.class,"money > ?","200.00");
最简单的方法是,使用 save() 方法更新 find() 找到的记录。
//查找表中id为1的记录
User user = LitePal.find(User.class,1);
user.setUserName("lisi");
user.save();
从LitePalSupport继承的每个实体类都有 update() 和 updateAll() 方法。你可以使用指定的id更新单条记录。
OrderForm order = new OrderForm();
order.setMoney(249.00f);
order.update(id);
还可以使用where条件更新多条记录。
OrderForm order = new OrderForm();
order.setMoney(249.99f);
order.updateAll("money = ?","249.00");
通过指定id在user表中查询单条记录。
User user = LitePal.find(User.class,id);
查询user表中的所有记录
List<User> list = LitePal.findAll(User.class);
复杂查询
List<User> list = LitePal.where("username like ? and age > ?", "zhang%", "18").order("age").find(User.class);
默认情况下,每个数据库操作都在主线程上。如果数据库操作可能花费很长时间,例如保存或查询大量记录。可以考虑使用异步操作,注意这是1.5.1之后才添加的方法。
LitePal支持所有crud方法上的异步操作,只需在方法名后拼接上Async这个关键词即可,如果要在后台线程上查找来自某表的所有记录,可以使用以下代码:
LitePal.findAllAsync(User.class).listen(new FindMultiCallback<User>() {
@Override
public void onFinish(List<User> list) {
//查询到的结果集将回调到此方法中
}
});
只需要使用 findAllAsync() 而不是 findAll(),并附加一个 listen() 方法,查找结果将在完成后回调到onFinish() 方法。
异步保存的用法和上面的方法是类似的,代码如下:
User user3 = new User();
user3.setUserName("wangwu");
user3.setPassword("password");
user3.setAge(24);
user3.saveAsync().listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
//保存结果将回调到此方法中
}
});
在LitePal中建立表间关系非常简单,在实体类创建时,里面放置一个其它实体类的对象,就做到了一对一的关联,如果放置的是实体类的集合,则是一对多的关联。
一对多的例子(描述一个用户有多个订单):
创建一个用户实体类
public class User extends LitePalSupport {
private String userName;
private String password;
//用户的订单列表
private List<OrderForm> orders;
// generated getters and setters.
...
}
创建一个订单实体类
public class OrderForm extends LitePalSupport {
private String number;
private float money;
// generated getters and setters.
...
}
如果你的应用需要多个数据库,LitePal完全可以支持。你可以在运行时创建任意数量的数据库。例如:
//创建数据库
LitePalDB litePalDB = new LitePalDB("demo2", 1);
//添加表
litePalDB.addClassName(User.class.getName());
litePalDB.addClassName(OrderForm.class.getName());
//使用该数据库
LitePal.use(litePalDB);
这将创建一个包含user和OrderForm表的demo2数据库。
如果只想创建一个与litepal.xml具有相同配置的新数据库,则可以使用:
LitePalDB litePalDB = LitePalDB.fromDefault("newdb");
LitePal.use(litePalDB);
可以使用以下命令切换回默认数据库:
LitePal.useDefault();
可以指定的数据库名称删除数据库:
LitePal.deleteDatabase("newdb");
如果你需要监听数据库的创建或升级事件,并在回调中填充一些初始数据,可以这样做:
LitePal.registerDatabaseListener(new DatabaseListener() {
@Override
public void onCreate() {
// fill some initial data
}
@Override
public void onUpgrade(int oldVersion, int newVersion) {
// upgrade data in db
}
});
-keep class org.litepal.** {
*;
}
-keep class * extends org.litepal.crud.DataSupport {
*;
}
-keep class * extends org.litepal.crud.LitePalSupport {
*;
}