Litepal——作为带我入行的第一本教学书籍《Android第一行代码》的作者郭霖老师所写出来的持久化框架,几乎算是我接触Android世界之后第一个遇到的框架,故将该框架列为一系列学习框架博客的首位。
根据Litepal的GitHub主页:Litepal,可以看到该框架的一些简介:
LitePal is an open source Android library that allows developers to use SQLite database extremely easy. You can finish most of the database operations without writing even a SQL statement, including create or upgrade tables, crud operations, aggregate functions, etc. The setup of LitePal is quite simple as well, you can integrate it into your project in less than 5 minutes.
事实上,正如这段简介所说,集成Litepal相当简单,不需要超过五分钟时间。使用Litepal,也适合对sql语言还不熟悉的开发者快速上手。
2.特性让我们继续浏览Litepal的GitHub主页,可以发掘Litepal的一些特性:
Using object-relational mapping (ORM) pattern. Almost zero-configuration(only one configuration file with few properties). Maintains all tables automatically(e.g. create, alter or drop tables). Multi databases supported. Encapsulated APIs for avoiding writing SQL statements. Awesome fluent query API. Alternative choice to use SQL still, but easier and better APIs than the originals. More for you to explore.用大白话来描述的话,可以列举如下:
Litepal使用了ORM(对象关系映射)模型 Litepal几乎是无配置的,仅需极少的配置文件 Litepal几乎包括所有的CRUD操作,也支持多张表格的操作 Litepal可以仅调用api进行CRUD操作而避免编写sql语句总之,看到Litepal具有这么多良好的特性,读者是否心动了呢。理论的话不多说,我们现在就开始正式地使用Litepal进行数据库的相关操作
PS:如果有曾经学习过Java的ORM框架——Mybatis的读者,应该不会对Litepal的使用太陌生,因为它们都使用了xml文件进行相应的配置
现在Android框架的集成相比于IDE还为ADT的时代,要方便了许多。原因是现在的主流IDE是Android Studio,而AS默认使用了Gradle进行版本的配置管理,这让集成框架变得简单了许多。
在build.gradle下,添加以下语句,然后重新sync,即可将Litepal集成到你的项目中:
implementation 'org.litepal.android:java:3.0.0'
当然,目前Android的主流开发语言,除了Java之外,还有Kotlin,Litepal同样具有Kotlin版本的(这里的演示仅针对Java,Kotlin版本的异曲同工)依赖:
implementation 'org.litepal.android:kotlin:3.0.0'
可以根据个人需求进行配置。
3.2 配置集成了Litepal之后,要想正式使用它还需要进行一些配置
在assets目录下新建litepal.xml,作为Litepal的全局配置文件,相应的条目信息已作出注释,代码如下:
<!-- -->
在你的应用下配置Litepal,有两种方式可以实现:
修改清单文件,将你的应用名修改为:android:name="org.litepal.LitePalApplication"
新建一个自己写的MyOwnApplication类,然后将清单文件中的应用名定位到该类,即:android:name="com.example.MyOwnApplication"
,然后再编写MyOwnApplication类,代码如下:
public class MyOwnApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LitePal.initialize(this);
}
...
}
两种方式亦可,Litepal的作者建议若使用第二种方式,需要尽快地调用
LitePal.initialize(this);
所以将其放在onCreate()
方法是最好的。
3.3 创建数据库
刚才在介绍的时候已经说过,Litepal采取的是对象关系映射(ORM)的模式,那么什么是对象关系映射呢?简单点说,我们使用的编程语言是面向对象语言,而使用的数据库则是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射了。
不过你可千万不要小看对象关系映射模式,它赋予了我们一个强大的功能,就是可以用面向对象的思维来操作数据库,而不用再和SQL语句打交道了,不信的话我们现在就来体验一下。像往常使用SQLiteOpenHelper类,为了创建一张Book表需要先分析表中应该包含哪些列,然后再编写出一条建表语句,最后在自定义的SQLiteOpenHelper中去执行这条建表语句。但是使用LitePal,你就可以用面向对象的思维来实现同样的功能了,定义一个Book类,代码如下所示:
package com.androidframelearn.dao_litapal;
import org.litepal.crud.LitePalSupport;
public class Book extends LitePalSupport {
private int id;
private String author;
private double price;
private int pages;
private String name;
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getAuthor(){
return author;
}
public void setauthor(String author){
this.author = author;
}
public double getPrice(){
return price;
}
public void setPrice(double price){
this.price = price;
}
public int getPages(){
return pages;
}
public void setPages(int pages){
this.pages = pages;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
这是一个典型的Java bean,在Book类中我们定义了 id、author,price, pages,name这几个字段,并生成了相应的getter和setter方法。相应你已经能猜到了,Book类就会对应数据库中的Book表,而类中的每一个字段分别对应了表中的每一个列,这就是对象关系映射直观的体验,现在你能够理解得更加清楚了吧。
接下来我们还需要将Book类添加到映射模型列表当中,修改litepal.xml中的代码,如下所示:
<!-- -->
这里使用标签来声明我们要配置的映射模型类,注意一定要使用完整的类名。不管有多少模型类需要映射,都使用同样的方式配置在标签下即可。
没错,这样就已经把所有工作都完成了,现在只要进行任意一次数据库的操作,BookStore.db数据库应该就会自动创建出来。为了更好地演示代码,我们将布局文件所需要的功能一次性编写好,activity_main.xml代码如下:
该布局效果如图所示:
<!-- -->
重新运行一下程序,再次创建数据库,就可以完美地完成数据库的升级了。这里的调试可以使用sqlite工具,这里不再赘述。
3.5 插入数据在讲述本节时,首先回顾一下之前添加数据的方法,我们需要创建出一个Contentvalues对象,然后将所有要添加的数据put到这个Contentvalues对象当中,最后再调用SQLiteDatabase的insert() 方法将数据添加到数据库表当中,步骤相当繁琐。
而使用LitePal来添加数据,这些操作可以简单到让你惊叹!我们只需要创建出模型类的实例,再将所有要存储的数据设置好,最后调用一下save()方法就可以了。
同样地,修改MainActivity,增加插入数据的事件方法,代码如下:
private void insertDatabyLitePal() {
btn_db_insert.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(16.96);
book.save();
Log.i(TAG,"插入数据成功");
}
});
}
同样运行程序,查看控制台,如图所示:
当点击查询数据(下一节将介绍该逻辑)时,控制台打印刚刚插入的数据,如图所示:
使用Litepal同样可以很轻易地查询数据,当然了,由于篇幅限制,这里仅仅贴出最简单的查询方式,至于关联查询等稍复杂的查询方式,可以去GItHub上参考Litepal的官方文档进行相关调用即可。
同样地,修改MainActivity,增加查看数据的事件方法,代码如下:
private void queryDatabyLitePal() {
btn_db_query.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List books = LitePal.findAll(Book.class);
for (Book book : books){
Log.i(TAG,"查询数据成功");
Log.d("MainActivity","书名是"+book.getName());
Log.d("MainActivity","书的作者是"+book.getAuthor());
Log.d("MainActivity","书的页数是"+book.getPages());
Log.d("MainActivity","书的价格是"+book.getPrice());
}
}
});
}
相关的运行结果上一小节以贴出,这里不再重复。
3.7 更新数据更新数据要比添加数据稍微复杂一点,因为它的API接口比较多,这里我们只介绍最常用的几种更新方式。
首先,最简单的一种更新方式就是对已存储的对象重新设值,然后重新调用save()方法即可。那么这里我们就要了解一个概念,什么是已存储的对象?
对于LitePal来说,对象是否已存储就是根据调用
model.isSaved()
方法的结果来判断的, 返回true就表示已存储,返回false就表示未存储。那么接下来的问题就是,什么情况下会返回true,什么情况下会返回false呢?实际上只有在两种情况下
model.isSave()
方法才会返回true, 一种情况是已经调用过model. save()方法去添加数据了,此时model会被认为是已存储的对象。另一种情况是model对象是通过LitePal提供的查询API查岀来的,由于是从数据库中查到的对象,因此也会被认为是已存储的对象。由于查询API相对复杂,因此只能先通过第一种情况来进行验证。修改MainActivity中的代码,如下所示:
private void updateDatabyLitePal() {
btn_db_update.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(510);
book.setPrice(19.95); // 第一次设置商品价格
book.save();
book.setPrice(10.99); // 第二次设置商品价格
book.save();
Log.i(TAG,"更新数据成功");
}
});
}
可以看到,我们做了跟插入数据类似的事情,但是我们对数据的价格进行了设置,运行程序,如图所示:
原创文章 269获赞 77访问量 6万+
关注
私信
展开阅读全文
作者:赈川