LitePal操作数据库
LItePal是一款开源的Android数据库框架,它采用了对象关系映射(ORM)的模式,并将我们平时开发常用的一些数据库功能进行封装
1.配置LitePal
因为大多数的开源项目都会将版本提交到jcenter上,这里只需要在app/build.gradle文件中声明该开源库的引用即可
声明方式如下:
1)编辑app/build.gradle文件,在dependencies闭包中最后一行添加如下内容:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.litepal.android:core:3.0.0'
}
这一行声明中,前面的部分是固定的,最后的3.0.0是版本号,即当前最新的版本号,这样就把LitePal成功引入到当前项目中
2)在app/src/main目录下新建assets目录,并在assets目录下新建litepal.xml文件,并编辑:
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="BookStore"></dbname>
<version value="2"></version>
<list>
//一定要用完整的类名
<mapping class="com.zjx.litepaltest.Book"></mapping>
<mapping class="com.zjx.litepaltest.Category"></mapping>
</list>
</litepal>
3)最后再配置LitePalApplication,修改AndroidManifest.xml文件中application代码:
<application
android:name="org.litepal.LitePalApplication"
...
...
...
</application>
2.创建和升级数据库
之前创建数据库是通过自定义一个类继承自SQLiteOpenHelper,然后在onCreate()方法中编写建表语句,现在LitePal采取的是对象关系映射(ORM)的模式,编程语言是面向对象语言,使用的数据库是关系型数据库,为两者之间建立一种映射关系,即对象关系映射。这种模式使我们可以用面向对象的思维来操作数据库。比如为了创建一张Book表,可以定义一个Book类:
public class Book {
private int id;
private String author;
private double price;
private int pages;
private String name;
private String press;
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;
}
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
}
并且修改litepal.xml中代码:
<list> //一定要用完整的类名 <mapping class="com.zjx.litepaltest.Book"></mapping> </list>
以上,所有的准备工作都已经完成,现在只需进行一次数据库的操作,BookStore就会自动创建,我们可以使用:
Connector.getDatabase();
这是一次最简单的数据库操作,运行程序即可创建数据库
数据库升级对我们来说就更加方便了:
要想改Book表结构可以向Book类中直接添加属性,要想添加表可以直接新建一个类并在<list></list>中添加<mapping></mapping>标签,改完这些东西,只需要将 <verson value="1"></version>中1改为2即可
3.使用LitePal添加数据
现有的Book类进行表管理时不需要任何继承结构,但进行CRUD时必须要继承LitePalSupport才行,然后就可以往Book表中添加数据,最后调用一下save()方法即可
//LitePal进行表管理时不需要模型类有继承结构,但进行CRUD操作时必须继承类。
// DataSupprot类被弃用,替换成LitePalSupport(调用其save()方法)
public class Book extends LitePalSupport {
...
...
}
Button createDatabase = this.<Button>findViewById(R.id.create_database);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setName("The JK Code");
book.setAuthor("Zhaojiexiong");
book.setPages(454);
book.setPrice(16.96);
book.setPress("Unkown");
book.save();
}
});
4.使用LItePal更新数据
最简单的更新方式是对已存储的对象重新设值,然后重新调用save()方法。那什么是已存储的对象?对象是否已存储是根据model.isSaved()的结果来判断的。一种情况是已经调用过save()方法去添加数据,另一种情况是model对象是通过LitePal提供的API查询出来的。第一种情况:
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setPrice(14.95);
book.setPress("Anchor");
book.save();
book.setPrice(10.95);
book.save();
}
});
使用上诉方式进行操作,限制性比较大,我们可以用另外一种更灵活的方式:
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setPrice(14.95);
book.setPress("Anchor");
book.updateAll("name = ? and author = ?","The Lost Symbol","Dan Brown");
//数据库表中的数据创建时已经被设为默认值,所以不能再通过set(0)方法更新为默认值
//LitePal提供了setToDefault()方法,传入相应的列名即可
// Book book = new Book();
// book.setToDefault("pages");
// book.updateAll(); //将页数更新为0
}
});
使用updateAll()时,当你想把一个字段的值更新为默认值,不可以使用set...(0/false/null)这种方式,必须使用setToDefault()方法,并传入相应列名即可。
5.删除数据
使用LitePal删除数据时有两种方法。第一种就是直接调用已存储对象的delete()即可。第二种是调用deleteAll()方法,与updateAll()类似。这里的deleteAll()方法是org.litepal.Operator类中的静态方法,所以使用前要导入
import static org.litepal.Operator.deleteAll;
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
deleteAll(Book.class,"price < ?", "15");
}
});
6查询数据
只需要调用findAll()方法,传入一个Class<T>对象即可,用于指定查询的表,其返回值是一个Book类型的List集合。同deleteAll方法一样,使用前需导入。
import static org.litepal.Operator.findAll;
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List<Book> books = findAll(Book.class);
for (Book book: books){
Log.d("MainActivity","book name is " + book.getName());
Log.d("MainActivity","book author is " + book.getAuthor());
Log.d("MainActivity","book pages is " + book.getPages());
Log.d("MainActivity","book price is " + book.getPrice());
Log.d("MainActivity","book press is " + book.getPress());
}
}
});
上面代码是遍历List集合中的Book对象,并将其中的信息全部打印出来。
查询数据还可以加入限制条件:
findFirst(Book.class):查询Book表中的第一条数据,返回Book类对象
findLast(Book.class):查询Book表中的最后一条数据,返回Book类对象
也可以通过连缀查询来定制更多功能:
select():指定查询哪几列的数据,返回FluentQuery对象
where():指定查询的约束条件,返回FluentQuery对象
order():指定结果的排序方式,默认为升序,返回FluentQuery对象
limit():指定查询结果的数量,返回FluentQuery对象
offset():指定偏移量,返回FluentQuery对象
List<Book> books = select("name").where("pages > ?","400").order("pages").limit(10).offset(10).find(Book.class);