-
LitePal简介
LitePal是一个开源的Android库,允许开发人员非常容易地使用SQLite数据库。
您无需编写SQL语句即可完成大部分数据库操作,包括创建或升级表,crud操作
,聚合函数等.LitePal的设置也非常简单,您可以在不到5个时间内将其集成到项目中
LitePal特征
· 使用对象关系映射(ORM)模式。
· 几乎为零配置(只有一个属性很少的配置文件)。
· 自动维护所有表(例如,创建,更改或删除表)。
· 支持多数据库。
· 封装的API,用于避免编写SQL语句。
· 令人敬畏的流畅查询API。
· 使用SQL的替代选择,但比原始API更容易使用
- 这里简单介绍下ORM(对象关系映射),通俗的讲就是将面向对象的语言和关系型数
据库建立一种映射关系,这就是对象关系映射了
- 而这种对象关系映射一般由JavaBean来实现,即创建一个JavaBean让其对应一张数
据库表,具体可以看下面的实例。
这里贴出LitePal的github地址,大家在以后使用过程中有任何问题可以直接查阅官方文档 litepal https://github.com/LitePalFramework/LitePal
-
项目配置litepal
- 首先,在app下的build.gradle中添加 各版本添加方式可能不同,具体以官网为主,此处使用最新版 3.0.0
dependencies {
implementation 'org.litepal.android:java:3.0.0'
}
- 在项目app/src/main目录下创建一个assets目录(directory),在assets中创建一个litepal.xml文件(可以右键new 选择file 输入litepal.xml)
在litepal.xml中添加如下代码
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="demo" />
<version value="1" />
<list>
</list>
</litepal>
dbname配置项目的数据库名称。
version配置数据库的版本。每次要升级数据库时,加上此处的值。
list配置映射类。
- 配置LitePalApplication (配置此项可以简化API,不用每次都传递context)
打开AndroidManifest.xml, 在application标签前标签中增加
android:name="org.litepal.LitePalApplication"
<manifest>
<application
android:name="org.litepal.LitePalApplication"
...
>
...
</application>
</manifest>
当然,您可能拥有自己的应用程序,并且已经在此配置,例如:
<manifest>
<application
android:name="com.example.MyOwnApplication"
...
>
...
</application>
</manifest>
!!!这时你需要调用LitePal.initialize(context)
public class MyOwnApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LitePal.initialize(this);
}
...
}
请务必尽早调用此方法。
在Application的onCreate()方法中调用就可以
并始终记得使用应用程序上下文作为参数。
不要将任何活动或服务实例用作参数,否则可能会发生内存泄漏。
至此litepal的配置工作已经完成了,我们发现,实际上我们并没有进行什么繁琐的配置,这也正是litepal的优点之一。
-
创建(升级)数据库
创建数据库
- 先创建一个litepaltest的项目,然后进行LitePal的配置
- 我们首先要指定数据库的名字,这里我们使用BookStore
<dbname value="BookStore" />
,现在只需要进行任意一次的数据库的操作,BookStore.db数据库就会自动创建出来 - 创建一个JavaBean即实体类名为Book.
Book类对应了数据库中的Book表,类中的每一个字段分别对应了表中的每一列
private class Book{
//private int id; id字段无需添加,litepal会自动添加id属性
private String author;
private double price;
private int pages;
private String name;
// ...此处省略getter和setter方法,大家不要忘记添加哦
}
tips: 使用Android Studio时可以使用快捷键alt + insert 选择getter and setter快速添加getter和setter方法
- 我们只是建立了JavaBean但还没有建立和litepal的联系,因此我们到litepal.xml的<mapping>中添加一行代码
<mapping class="com.example.litepaltest.Book"></mapping>
这里要写入类的完整类名,我们添加其他映射也是如此方式
- 在activity_main的布局文件中增加一个Button名为Create_DB,在Activity中为其设置点击事件
Button createDB = findViewById(R.id.create_db);
createDB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Connector.getDatabase();
}
});
注意,此处的Connector要导入import org.litepal.tablemanager.Connector;这个包,大家不要导错包了
- 运行程序,点击button,数据库就会自动创建完成了
- 让我们用adb shell看下数据库创建情况
可以看到数据库已经创建完成了,并且生成了三张表,Book是我们自己定义的
表,android_metadata无须在意,table_schema时LitePal内部使用的
升级数据库
- 当我们想要升级数据库,比如说是添加或者修改表时应该进行如下的操作
- 先向Book表中增加个press属性,打开Book类加入如下代码
private String press;
// 此处省略getter和setter方法
- 再增加一张Category表,按照ORM的思想,我们需要增加Category类并且添加<mapping>
private class Category{
//private int id; 可以不加
private String categoryName;
private int categoryCode;
.... // 省略getter和setter方法
}
<list>
...
<mapping class="com.example.litepaltest.Category"></mapping>
</list>
使用litepal升级的好处就是能够为我们保存之前表中的数据
现在我们可以重新运行代码,点击Create DB,然后使用.tables查看数据库中的表
可以看到已经升级成功了
CRUD操作
!注意,观察我们之前的实体类,它们是没有继承自任何类的,并且这不影响我们创建数据库的操作,但是进行CRUD时,我们需要让其继承自LitePalSupport类,我们需要先修改下代码,让Book类和Category类都继承自LitePalSupport
老版本的litepal是继承自DataSupport,但是新版中找不到这个类,而翻阅官方文档中,是继承自LitePalSupport,因此在我们使用中也要经常翻阅官方文档
增加数据
我们在使用litepal进行增加数据的时候,只需要创建出模型类的实例,然后设置数据,最后调用下save()方法就好。下面让我们来实践一下- 在activity_main中增加一个add_data的Button
- 在Mainactivity中添加add_data的点击事件
Button addData = findViewBId(R.id.add_data);
addData.setOnclickListener(new View.OnClickListener() {
@Override
public void onCLick(View v){
Book book = new Book();
book.setName("The Da Vinci Code");
book.setAuthor("Dan Brown");
book.setPages(454);
book.setPrice(15.98);
book.setPress("unknow");
book.save();
}
});
- 现在运行程序,点击AddData按钮,打开BookStore.db输入
select * from Book
就可以看到,数据已经添加到表中了
可以看到,虽然我们没有添加id,但是litepal依然自动为我们添加了一个主键id。
更新数据
LitePal中对于更新数据的API比较多,这里介绍几种常用的
- 第一种是对已存储的对象重新赋值,然后再次调用save()方法
已存储对象,model.save()添加的数据和通过查询方法从数据库中查出来的对象被认为是已存储对象,通俗的说就是已经存到数据库中的对象,我们可以通过
model.isSaved()
方法进行判断,已存储则会返回true
让我们验证一下
activity_main.xml中增加一个update Button,在Mainactivity中为其设置点击事件
Button updateData = findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Book book = new Book();
book.setName("The Lost Symbol");
book.setAuthor("Dan Brown");
book.setPages(512);
book.setPrice(12.18);
book.setPress("unknow");
book.save();
// 这里我们修改book的价格
book.setPrice(10.1);
// 再次保存
book.save();
}
});
现在让我们运行程序点击update data按钮,然后再次查询数据库表
可以看到,书的价格是我们更新后的价格。
- 第一种方法局限性较大,现在让我们来看第二种方法,用于更新多条数据
修改更新按钮的点击事件
@Override
public void onClick(View v){
Book book = new Book();
book.setPrice(9.9);
book.setAuthor("Anchor");
book.updateAll("name = ? and author = ?", "The Lost Symbol", "Dan Brown");
};
现在重新运行程序,意料之中的,第二本书的价格和作者变成了我们设置的
updateAll()中可以指定一个条件约束,类似于sql中的where语句,如果不指定则表示更新所有语句
- 当想要只更新一条数据的时候我们也可以采用这种方法,修改更新按钮中的点击方法
Book book = LitePal.find(Book.class, 2);
book.setAuthor("JayJay");
book.save();
运行程序可以看到更新成功
这里我们使用了LitePal的find()方法,方法传入两个参数,一个是Class,一个是key,就是表的主键,我们通过此方法获得到Book对象,然后使用model.save()进行更新,这是非常常用的一种方法。
删除数据
删除方法我们可以使用LitePal的delete()方法,此方法传入两个参数,分别为Class和key,key即为主键。
我们新建一个delete的Button,为其设置点击事件
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LitePal.delete(Book.class, 2);
}
});
运行代码,然后查询表发现数据已经被删除了
我们也可以调用LitePal的deleteAll()方法删除多条数据
LitePal.deleteAll(Song.class, "duration > ?" , "350");
这个方法传入三个参数,第一个为Class,第二个是条件,类似于sql中的where,其中的?是占位符,后面的参数按照位置依次填充到?中
接下来让我们来测试下,首先添加两条价格为100的数据
修改删除按钮的点击事件
@Override
public void onClick(View v) {
// LitePal.delete(Book.class, 2);
LitePal.deleteAll(Book.class, "price > ?", "99");
}
运行程序点击删除,再来看下数据库表,可以看到删除成功了
查询数据
- LitePal.find(Class, long id)这个方法前面已经多次使用,它返回一个T对象
- LitePal.findAll(Class)返回所有对象,即返回表中所有数据
- 我们也可以进行复杂的查询
List<Song> songs = LitePal.where("name like ? and duration < ?", "song%", "200").order("duration").find(Song.class);
如上段代码.where
代表查询的条件,依旧使用占位符的形式,并且支持sql中的通配符 如% _ 等
.order
代表了排序 我们也可以在order中跟上asc或者desc表示升序或降序
order("age desc")
也可以写两个 order(“age”, “size”)
这里不再举例,大家可以自行尝试。