LitePal(版本1.5.0,写此博客时是最新版本)

时间:2023-02-06 20:12:43


一,概述

今天按惯例打开郭霖大神的微信公众号,看看有没有什么干货之类的文章(其实郭神推送的文章都是满满的干货,嘻嘻)。然后发现郭神的LitePal竟然有了新版本,到了LitePal1.5.0,我的天啊,请允许我表达一下激动的心情。最初知道LitePal是在去年(好像是去年)翻郭神的博客时看见了他写的关于LitePal的专栏博客,当时看那个博客的时间是2015年以前的,也就没在意,心想这技术肯定有点老了,不去了解也罢(从我的这个想法可以看出,我还是Too Young了)。去年郭神《第二行代码》首发,我抢了一本签名版(郭神的字好漂亮),书一到手上就迫不及待的翻了起来,然后在《第二行代码》的第六章又邂逅了LitePal1.3.2,不知是忙还是懒,也没有引起重视,连Demo都没敲一个,真是服了自己,该打!终于在2017年三八妇女节的前一天,也就是传说中的女生节(What节?)这一天,我决定不再错过Litepal。

二,配置LitePal1.5.0

我使用的IDE是Android Studio2.2,如果正在看这篇博客的你还在使用Eclipse搞Android开发,我强烈建议你马上去安装一个AS,使用AS开发Android是大势所趋,好处也特别多。不多说,进入正题。如何配置LitePal1.5.0,可以参考GitHub上郭神给出的示例,链接在此 https://github.com/LitePalFramework/LitePal

首先,在AS中新建一个工程,在app/build.gradle文件的dependencies闭包中添加一行内容:compile 'org.litepal.android:core:1.5.0',然后Sync Now同步一下。

接下来,右击app/src/main目录-->New-->Directory,创建一个assets目录,然后在assets目录下再新建一个litepal.xml文件,将LitePal上的那一段代码粘贴过来即可。LitePal.xml文件里面的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<litepal>
<!--
Define the database name of your application.
By default each database name should be end with .db.
If you didn't name your database end with .db,
LitePal would plus the suffix automatically for you.
For example:
<dbname value="demo" />
-->
<dbname value="demo" />

<!--
Define the version of your database. Each time you want
to upgrade your database, the version tag would helps.
Modify the models you defined in the mapping tag, and just
make the version value plus one, the upgrade of database
will be processed automatically without concern.
For example:
<version value="1" />
-->
<version value="1" />

<!--
Define your models in the list with mapping tag, LitePal will
create tables for each mapping class. The supported fields
defined in models will be mapped into columns.
For example:
<list>
<mapping class="com.test.model.Reader" />
<mapping class="com.test.model.Magazine" />
</list>
-->
<list>
</list>

<!--
Define where the .db file should be. "internal" means the .db file
will be stored in the database folder of internal storage which no
one can access. "external" means the .db file will be stored in the
path to the directory on the primary external storage device where
the application can place persistent files it owns which everyone
can access. "internal" will act as default.
For example:
<storage value="external" />
-->

</litepal>

可以将这些注释的东西看完之后统统删掉,留着也并没什么用。

最后,自己新建一个MyApplication.java继承自Application类,并且在onCreate方法中初始化一下LitePal,一行代码搞定如下:

@Override
public void onCreate() {
super.onCreate();
//初始化
LitePal.initialize(this);
}
并且还要在AndroidManifest.xml文件中配置一下刚刚我们自己新建的MyApplication:

<application
android:name=".application.MyApplication"
......

至此,Litepal的配置工作就完成了,接下来,去感受LitePal的强大之处吧。

三,创建和升级数据库

先贴一个Java bean的代码如下:

package com.bighuan.litepaldemo.model;

import org.litepal.crud.DataSupport;

/**
* 项目名: LitePalDemo
* 包名: com.bighuan.litepaldemo.model
* 文件名: Phone
* 作者: LH
* 邮箱: abighuan@126.com
* 创建时间:2017/3/7 15:39
* 描述: 手机bean
*/


public class Phone extends DataSupport {

private int id;

private String name; //手机名

private float price;//价格

private String brand;//品牌

private double discount;//打折

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public float getPrice() {
return price;
}

public void setPrice(float price) {
this.price = price;
}

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public double getDiscount() {
return discount;
}

public void setDiscount(double discount) {
this.discount = discount;
}
}

大家可以先忽略为什么Phone继承了DataSupport。估计大家也猜到了Phone类会对应到数据库中的Phone表,而该类中的每一个字段对应表中一个列。你可能会有疑问,我数据库都没建呢?别急嘛,还记得litepal.xml这个文件吗,它要出场了。只要在它里面配置就行了,示例和解释都如下:

<?xml version="1.0" encoding="utf-8"?>
<litepal>
<!--PhoneMall就是数据库名,自己取名就可以了-->
<dbname value="PhoneMall" />
<!--下面的这个1表示版本,第一次就是1了-->
<version value="1" />
<!--Phone类也要添加到映射模型列表中,注意一定要是完整类名-->
<list>
<!--Phone类对应数据库中的Phone表,将Phone类映射到模型列表中-->
<mapping class="com.bighuan.litepaldemo.model.Phone"></mapping>
</list>
</litepal>
接下来,只要在代码中创建数据库即可。

使用建工程时默认的那个MainActivity,其对应的activity_main.xml里面有5个按钮,分别是创建数据库,添加数据,更新数据,删除数据,查询数据,代码如下(其实也没什么好贴的):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.bighuan.litepaldemo.activity.MainActivity">

<Button
android:id="@+id/main_btn_create_db"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="创建数据库"/>
<Button
android:id="@+id/main_btn_add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加数据add"/>
<Button
android:id="@+id/main_btn_update_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更新数据update"/>
<Button
android:id="@+id/main_btn_delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除数据delete"/>
<Button
android:id="@+id/main_btn_query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询数据query"/>
</LinearLayout>
创建数据库的点击事件:

 //创建数据库(我的天,这也太简洁了吧)
Connector.getDatabase();
当时我确实吃惊了,怎么可以这么简单呢,但这就是LitePal的强大之处。

如果你觉得Phone表中还要增加字段,直接在Phone.java增加就可以了,然后将litepal.xml中的版本号加一即可,然后重新创建数据库就可以。

四,使用LitePal添加数据

先贴代码,然后解释:

 /**
* 插入数据
*/
private void addData() {
//添加数据
Phone phone = new Phone();
phone.setId(001);
phone.setName("小米mix");
phone.setPrice(3999);
phone.setBrand("小米");
phone.setDiscount(0.95);

phone.save();//1,主线程运行


/* phone.saveAsync().listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
if (success) {
Toast.makeText(MainActivity.this, "插入数据成功了", Toast.LENGTH_LONG).show();
}
}
});//,2,子线程运行,并且所有异步操作回到onFinish()方法之后都会切回到主线程,厉害了*//*


phone.saveOrUpdateAsync().listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
Toast.makeText(MainActivity.this, "插入数据成功了", Toast.LENGTH_LONG).show();
}
});
phone.saveOrUpdate("name=?", phone.getName());//已存在就更新,不存在就创建*/

}
如果通过LitePal进行增删改查操作,必须让我们的java bean继承DataSupport类就可以啦,所以前面贴代码时我继承了DataSupport的原因。我们只要new 一个Phone对象出来,设置好我们要插入的数据,然后直接phone.save();就OK了。但是在我注释的代码了还有phone.saveAsync().listen(...)这种代码,这又代表什么呢?前者是在主线程运行,后者是在子线程运行,但回调的onFinish()确实在主线程的,可以修改UI,这就厉害了,这也是LitePal1.5.0相比之前版本退出的重磅功能。之后介绍LitePal的更新数据方法也是这样。当我们操作的数据过多时(如插入几万条数据)可能会阻塞主线程时,就有必要在子线程中操作了。在代码中都有注释,相信你们看的懂。接下来就是贴代码了。

五,使用LitePal更新数据

 /**
* 更新数据
*/
private void updateData() {
Phone phone1 = new Phone();
phone1.setName("小米note2");
phone1.setPrice(2799);
//phone1.updateAll("name = ? and price = ?","小米mix","3999");
phone1.updateAllAsync("name = ? and price = ?", "小米mix", "3999").
listen(new UpdateOrDeleteCallback() {
@Override
public void onFinish(int rowsAffected) {
Toast.makeText(MainActivity.this, "更新操作影响了" + rowsAffected + "行数据",
Toast.LENGTH_LONG).show();
}
});
}

六,使用LitePal删除数据

 /**
* 删除数据
*/
private void deleteData() {
DataSupport.deleteAllAsync(Phone.class, "price < ?", "2800").
listen(new UpdateOrDeleteCallback() {
@Override
public void onFinish(int rowsAffected) {
Toast.makeText(MainActivity.this, "删除操作影响了" + rowsAffected + "行数据",
Toast.LENGTH_LONG).show();
}
});
}

七,使用LitePal查询数据(相对前面来说,查询比较复杂,相对sql来说,还是挺简单的)

 /**
* 查询数据,方法比较多
*/
private void queryData() {
//直接将Phone表中的所有数据查了出来
List<Phone> phones = DataSupport.findAll(Phone.class);
Log.d("MainActivity", phones.toString());

//查询第一条数据
Phone firstPhone = DataSupport.findFirst(Phone.class);
//最后一条
Phone lastPhone = DataSupport.findLast(Phone.class);

//通过select()方法查找数据,只查name,price两列数据
List<Phone> phones1 = DataSupport.select("name", "price").find(Phone.class);

//通过where指定约束条件,查询价格大于2800的手机
List<Phone> phones2 = DataSupport.where("price > ? ", "2800").find(Phone.class);

//order()方法,示例是将查询结果按价格由低到高排序,默认就是asc,desc则是相反
List<Phone> phones3 = DataSupport.order("price asc").find(Phone.class);
//只查前四条数据
List<Phone> phones4 = DataSupport.limit(5).find(Phone.class);

//还可以通过offset()来指定偏移量,示例表示查到了第3,4,5条数据
List<Phone> phones5 = DataSupport.limit(3).offset(2).find(Phone.class);

//同时也可以将以上的的几个方法任意的连缀组合从而完成复杂的查询操作
DataSupport.select("name", "price", "discount")
.where("price > ?", "2800")
.order("id")
.limit(5)
.offset(5)
.find(Phone.class);
}

八,总结

LitePal这么强大,肯定还有一些功能没介绍到,大家可以去关注郭霖大神的博客专栏,微信公众号(每个工作日都有干货文章哦),GitHub主页。写这篇博客竟然花了我几小时时间,也挺值得的,希望自己可以坚持写一些技术博客吧!再见啦!