Android 数据库存储插件——LitePal

Android Litepal 数据库存储

LitePal介绍

LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式,将平时开发常用的数据库(SQLite)的功能进行了封装,开发者无需编写SQL语句即可完成所有数据库有关的基本操作。更重要的是LitePal非常轻量级,jar包只有不到100k大小,非常易于管理,非常容易上手。目前LitePal的源码已在GitHub上开源,这是链接。注意:此篇博客基于LitePal3.0.0并使用Java编写开发。

LitePal使用——导入依赖

方式一:下载jar
点击这里下载Jar包下载并导入依赖。
方式二:在你的项目(build.gradle)中加入依赖并同步项目。
dependencies {
implementation ‘org.litepal.android:java:3.0.0’
}

LitePal使用——创建配置文件

首先我们需要创建一个assets的文件夹,如图所示。新建aseets文件的具体步骤,请参见何时不少年的博客。
Android 数据库存储插件——LitePal_第1张图片
接下来我们需要一个xml配置文件:litepal.xml,注意:此文件名只能为litepal.xml,不能为其他文件名且必须在aseets中,否则LitePal会找不到配置文件。文件的配置如下:




    
    

    
    

    
    

    


LitePal使用——配置数据库的上下文

数据库操作需要使用到Context,但是我们并不希望每次使用时都去传一此这个参数,那样的话数据库操作将会非常繁琐,所以LitePal只需要在AndroidManifest.xml中配置一下Application,这样就不用再多次传递Context了(真正一次配置,处处使用)。
Android 数据库存储插件——LitePal_第2张图片
但是如果你有你的程序,并且已经在此配置,不希望改动原有的配置,例如:
Android 数据库存储插件——LitePal_第3张图片
没有问题,LitePal依然可以使用,只需要在你的应用程序中调用:LitePal.initialize(context); 像这样:

package com.sin998.testlitepal;

import android.app.Application;

import org.litepal.LitePal;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        LitePal.initialize(this);
    }
}

注意:请务必尽早调用此方法。可以在Application 的onCreate()方法中调用。并始终记得使用应用程序上下文作为参数。不要将任何activity或service实例用作参数,否则可能会发生内存泄漏。到此,LitePal的配置完毕。

LitePal使用——创建表

根据对象关系映射模式的理念,每个表都要对应一个模型。简而言之,如果我们想创建出一张表,那么就要有一个与此表对应的模型类。这需要继承LitePalSupport类。

package com.sin998.testlitepal.bean;

import org.litepal.annotation.Column;
import org.litepal.crud.LitePalSupport;

public class Student extends LitePalSupport {

    /*
     *注意:id字段可写可不写,因为不管你的实体类有没有这个字段,LitePal
     *都会默认创建一个id字段(若实体类中有则不会创建),因为每个表都必须要
     *一个主键,作为此表的索引,id字段即为索引。
     */
    private int id;
    private String pname;
    private int psex;
    private double pscore;
	
	//getter和setter方法
}

LitePal还支持注解的使用,例如:

    @Column(nullable = true)
    private int id;

此注解表示为列设置可空约束(传入boolean)。除此之外还有以下三种注解:

    @Column(ignore = false)
    private String pname;

忽略将此字段映射到列(传入boolean)。

	@Column(unique = false)
    private int psex;

为列设置唯一约束。(传入boolean)。

    @Column(defaultValue = "60.00")
    private double pscore;

使用字符串类型为列设置默认值,不管列类型是什么(传入String)。
注意:注解的默认值为:

	@Column(nullable = true)
    @Column(ignore = false)
    @Column(unique = false)
    @Column(defaultValue = "")

接下来回到之前的配置文件litepal.xml,添加如下代码,新增映射关系:


    
        
        
        
        
    

注意:这里有一个技巧(我觉得应该算吧),只要按住ctrl并将鼠标移动到实体类上,点击能跳转到实体类即代表配置正确。例如:
Android 数据库存储插件——LitePal_第4张图片
下次操作数据库时将自动生成表。例如,你通过如下代码可以获取SQLiteDatabase:

SQLiteDatabase db =  LitePal.getDatabase();

LitePal支持的映射数据类型一共有8种,分别是:

int、short、long、float、double、boolean、String、Date

现在LitePal将会自动生成如下SQL语句:

CREATE TABLE student(
	id INT NOT NULL PRIMARY KEY auto_increment,
	pname CHAR,
	psex INT,
	pscore DOUBLE
);

LitePal使用——升级表

LitePal升级表格非常简单。只需要修改你的实体类:

package com.sin998.testlitepal.bean;

import org.litepal.annotation.Column;
import org.litepal.crud.LitePalSupport;

public class Student extends LitePalSupport {

    /*
     *注意:id字段可写可不写,因为不管你的实体类有没有这个字段,LitePal
     *都会默认创建一个id字段(若实体类中有则不会创建),因为每个表都必须要
     *一个主键,作为此表的索引,id字段即为索引。
     */
    private int id;
    private String pname;
    @Column(defaultValue = "60.00")
    private double pscore;
	
	//getter和setter方法
}

然后在litepal.xml中升级数据库版本号:

    

这些表将在你下次运行数据库的时候升级。pname列将会被删除,其他列将会保留,pscore列的默认值修改为"60.00"。
但是有些升级条件是LitePal无法处理的,升级表中的所有数据都将被清除:

  • 添加注释为的字段unique = true。
  • 将字段的注释更改为unique = true。
  • 将字段的注释更改为nullable = false。

注意上述会导致数据丢失的情况。

LitePal使用——插入数据

LitePal对于数据操作十分便捷。从LitePalSupport继承的每个模型将提供save()方法。若是没有使用LitePal,我们想向表中插入一条数据需要SQLiteDatabase、ContentValues,然后一条一条通过values.put("","");来组装数据,最后再通过db.inset()插入。整个过程十分繁琐,写代码体验极其不好。但是现在你只需要:

Student createStudent = new Student();
createStudent.setPname("sin998");
createStudent.setPsex(1);
createStudent.setPscore(60.00);
createStudent.save();

运行程序,点击三次插入,再查看数据库中的数据:
Android 数据库存储插件——LitePal_第5张图片
数据保存成功。
由于save()方法是有返回值的,true代表成功,false代表失败。
Android 数据库存储插件——LitePal_第6张图片
因此我们可以根据此方法改写代码以判断数据是否插入成功,例如:

Student createStudent = new Student();
createStudent.setPname("sin998");
createStudent.setPsex(1);
createStudent.setPscore(60.00);
createStudent.save();
if (createStudent.save()) {
	Toast.makeText(this, "插入数据成功", Toast.LENGTH_SHORT).show();
} else {
    Toast.makeText(this, "插入数据失败", Toast.LENGTH_SHORT).show();
}

但如果你更希望在插入数据失败时直接抛出异常(这有益于我们快速定位问题所在),那么你可以使用saveThrows();来替代,例如:

createStudent.saveThrows();

一般情况上述方法运行在UI线程,如果你的UI线程十分繁忙,但现在又需要插入大量的数据,不能再进行耗时操作(会有crash风险),那么你可以使用异步来插入数据,例如:

createStudent.saveAsync().listen(new SaveCallback() {
    @Override
    public void onFinish(boolean success) {
        //TODO:插入完成后的操作
    }
});

注意:LitePal的所有(没错,就是所有)数据库操作都支持异步,都可以在异步之后调用listen方法以监听操作完成,为节省篇幅,下文只调用异步,监听需读者自己编写。

LitePal使用——更新数据

LitePal的更新数据也同样简单,LitePal提供两种更新方式。
方式一:如果你知道id,想根据id来更新指定的数据,其原理是先根据id把信息查询出来,然后在set值,最后再调用save();把原先的值覆盖掉:

//第二个参数就传要更新的id
Student updateStudentById= LitePal.find(Student.class,1);
updateStudentById.setPname("这是修改的名字");
updateStudentById.setPsex(0);
updateStudentById.setPscore(100.00);
if (updateStudentById.save()) {
	Toast.makeText(this, "更新数据成功", Toast.LENGTH_SHORT).show();
	} else {
	Toast.makeText(this, "更新数据失败", Toast.LENGTH_SHORT).show();
}

重新运行程序,更新数据,再次查看数据库。
Android 数据库存储插件——LitePal_第7张图片
数据更新数据成功。
如果你想直接new出实体类然后再根据id来更新数据:

Student updateStudentById = new Student();
updateStudentById.setPname("这是更新的数据:我是直接new的student类");
updateStudentById.update(1);

运行程序,更新数据,查看数据库:
Android 数据库存储插件——LitePal_第8张图片
数据更新成功。
同样的,LitePal在更新数据时会返回更新了几条数据:
Android 数据库存储插件——LitePal_第9张图片
通过这个方法你可以把打log出来或者记录到日志中,便于记录、维护和管理。
同样的,如果你需要异步更新数据,你可以:

updateStudentById.updateAsync(1);

方式二:如果你想根据条件来更新所有的满足条件的数据:

Student updateStudentByConditions = new Student();
updateStudentByConditions.setPscore(100.00);
updateStudentByConditions.updateAll("pname = ? and psex = ? ","sin998","1");

学过Mysql的朋友应该猜到了,这很像sql的where语法,是的,就是它。
第一个参数接收一个字符串,相当于sql中的where部分,其中"?“将会与依次与后面的参数对应(”?"起一个占位作用,相当于占位符)。注意:这里的字段是你实体类的字段。运行程序,更新数据,查看数据库:
Android 数据库存储插件——LitePal_第10张图片
数据更新成功。同样的,若是你想使用异步方式:

updateStudentByConditions.updateAllAsync("pname = ? and psex = ? ", "sin998", "1");

方式三:将数据更新成默认值:
为了演示效果,我把数据库升级,将pscore字段的默认值设置为60.00:

@Column(defaultValue = "60.00")
private double pscore;

添加更新数据代码:

Student updateStudentToDefault = new Student();
updateStudentToDefault.setToDefault("pscore");
updateStudentToDefault.updateAll("pname = ? and psex = ? ", "sin998", "1");

运行程序,更新数据,查看数据库:
Android 数据库存储插件——LitePal_第11张图片
哎,我们设置的默认值不是60吗?怎么更新成0了…反复检查代码也没问题。
想要把一个字段更新成默认值(默认值就是当你new了一下model类,其里面的变量就会有默认值,int是0,double和float是0.0,boolean是false,String是null等等)。修改代码,运行程序,打印日志(方法logdStuInfo(Student student)的功能是把传入student的信息打印出来):
Android 数据库存储插件——LitePal_第12张图片
从日志可以看出,module类一new出来的时候就LitePal就马上会给字段赋上默认值。

LitePal使用——删除数据

LitePal的更新数据操作与删除数据操作大同小异。
方式一:通过id来删除数据

 LitePal.delete(Student.class,1);

方式二:根据约束删除

LitePal.deleteAll(Student.class,"pname = ?","sin998");

同样的,delete方法也有返回值,返回int,表示影响了几行(包括级联删除行),你同样可以得到这些信息:
Android 数据库存储插件——LitePal_第13张图片
deleteAll方法
并且delete也支持异步:

LitePal.deleteAsync(Student.class, 1);
LitePal.deleteAllAsync(Student.class,"pname = ?","sin998");

LitePal使用——查询数据

终于到了查询数据了,查询数据才是让人又爱又恨。但是LitePal同样强大,你甚至可以花式查询你所需要的数据。
方式一:根据id查询

Student student = LitePal.find(Student.class,1);

方式二:查询所有数据

List allStuList = LitePal.findAll(Student.class);

方式三:根据约束查询

List stuList = LitePal.where("pname = ?","sin998").order("id desc").find(Student.class);

除此之外,LitePal还提供了很多方法便于我们使用(这跟SQL语法很相似),请根据自己项目的实际需要选择合适的方法,想深入了解请查阅源码,这里不在赘述:
Android 数据库存储插件——LitePal_第14张图片

LitePal使用——其他

你可以在运行时创建任意数量的数据库。例如:

LitePalDB litePalDB = new LitePalDB("demo", 1);
litePalDB.addClassName(Student.class.getName());
LitePal.use(litePalDB);

注意:你需要先提前定义好实体类,在需要的地方创建,上面的语句会创建名为"demo"的数据库,里面的表映射于Student实体类,然后LitePal将当前操作的数据库切换为demo。
如果你想创建一个新数据库并且配置和litepal.xml相同:

LitePalDB litePalDB = LitePalDB.fromDefault("newdb");
LitePal.use(litePalDB);

切换回默认的数据库:

LitePal.useDefault();

删除数据库:

LitePal.deleteDatabase("test");

监听数据库创建/升级

LitePal.registerDatabaseListener(new DatabaseListener() {
    @Override
    public void onCreate() {
    	// fill some initial data
    }

    @Override
    public void onUpgrade(int oldVersion, int newVersion) {
    	// upgrade data in db
    }
});

LitePal:github官网
项目所有源码已托管到github,点击这里进入
编写不易,转载请注明文章出处,谢谢!

你可能感兴趣的:(Android)