Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

ORM数据库框架 LitePal SQLite


目录

简介

Demo地址

GitHub

litepal-1.6.1.jar

litepal-1.6.1-src.jar

An Android library that makes developers use SQLite database extremely easy.

LitePal是一个开源的Android库,允许开发人员非常容易地使用SQLite数据库。 您可以完成大部分数据库操作,而无需编写SQL语句[statement],包括创建或升级表,crud操作,聚合函数[aggregate functions]等。LitePal的设置也非常简单,您可以在不到5分钟内将其集成到项目中。

特性

  • 使用对象关系映射[object-relational mapping,ORM]模式。
  • 很“轻”,jar包只有100k不到,使用起来比较简单
  • 几乎为零配置,只有一个属性很少的配置文件。
  • 自动维护[Maintains]所有表。例如,创建、更改或删除表。
  • 支持多数据库。
  • 封装的API,用于避免编写SQL语句。
  • 极好用的流式查询API。
  • 作为替代选择,你仍可使用SQL,但使用起来比原始API更易用。

LitePal不管是创建数据库、创建表还是执行增删改查,都是根据Model的类名和属性名,每次都需要进行反射拼装,然后调用Android原生的数据库操作,实现相应的功能。

使用过程

  • 首先引入lib,可以通过gradle引入也可以将下载的litepal.jar包直接放入libs目录下。
  • 然后在assets目录下新建一个 litepal.xml 文件,文件名称不能更改。
  • 然后在 AndroidManifest 中配置一下 LitePalApplication,如果已使用自定义的Application,只需在你的Application的onCreate方法中调用 LitePal.initialize(this) 即可。
  • 接下来创建继承自DataSupport的Mode类,之后这些实体类就拥有了进行CRUD操作的能力,LitePal框架会自动创建好相应的数据表,以及表数据类型和非空约束等。

配置

添加依赖

implementation 'org.litepal.android:java:3.0.0' //2018-10月最新版本
//implementation 'org.litepal.android:kotlin:3.0.0' //kotlin

配置 litepal.xml

在项目的 assets 目录中创建一个 litepal.xml文件,并按以下方式配置。

几个标签的作用:

  • dbname:配置数据库名称
  • version:配置数据库版本每次要升级数据库时,此处的值加1
  • list:配置映射类
  • storag:配置数据库文件的存储位置,只能选择【internal】或【external】

示例:

<?xml version="1.0" encoding="utf-8"?>
<litepal>
<!--定义应用程序的数据库名称。默认情况下,每个数据库名称应以.db结尾。如果您没有使用.db命名数据库端,LitePal会自动为您添加后缀。-->
<dbname value="demo" /> <!--定义数据库的版本。每次要升级数据库时,version标记都会有所帮助。修改您在映射标记中定义的模型,只需将版本值加1,数据库升级将自动处理,你无需关心。-->
<version value="1" /> <!--定义模型,LitePal将为每个映射类创建表。模型中定义的受支持字段将映射到列中。-->
<list>
<mapping class="com.test.model.Reader" />
<mapping class="com.test.model.Magazine" />
</list> <!--定义.db文件的位置。【internal】表示.db文件将存储在内部存储的数据库文件夹中,无人可以访问(默认值)。【external】表示.db文件将存储在主外部存储设备所在目录的路径中,应用程序可以放置它拥有的每个人都可以访问的持久文件。-->
<storage value="external" />
</litepal>

配置 LitePalApplication

如果没有自定义Application:android:name="org.litepal.LitePalApplication"

如果已自定义Application:LitePal.initialize(this);

始终记得使用 application 作为参数。不要将任何 activity 或 service 等的实例用作参数,以避免内存泄漏。

API

创建表

首先定义模型,例如:

public class Album extends LitePalSupport {
@Column(unique = true, defaultValue = "unknown")
private String name;
private float price;
private byte[] cover;
private List<Song> songs = new ArrayList<Song>();
// generated getters and setters.
...
}
public class Song extends LitePalSupport {
@Column(nullable = false)
private String name;
private int duration;
@Column(ignore = true)
private String uselessField;
private Album album;
// generated getters and setters.
...
}

注意,3.0.0之后是继承自 LitePalSupport,之前是继承自 DataSupport

然后将这些 models 添加到litepal.xml的 list 标签中:

<list>
<mapping class="org.litepal.litepalsample.model.Album" />
<mapping class="org.litepal.litepalsample.model.Song" />
</list>

下次操作数据库时将生成上面添加的数据库表。

LitePal不管是创建数据库、创建表还是执行增删改查,都是根据Model的类名和属性名,每次都需要进行反射拼装,然后调用Android原生的数据库操作,实现相应的功能。

更新表

LitePal中的升级表非常简单,只需修改你想要的模型:

public class Album extends DataSupport {
...
@Column(ignore = true)
private float price;//忽略掉此字段
private Date releaseDate;//添加此字段
}

添加了 releaseDate 字段,并给 price 字段添加了 ignore 注解用以忽略。

然后增加 litepal.xml 中的版本号:<version value="2" />

这些表将在您下次运行数据库时升级,升级后 releaseDate 列将添加到 album 表中,原始的 price 列将被删除。

升级后,除了那些删除的列之外,album 表中的所有数据都将被保留。

但是有些升级条件下LitePal无法兼容的处理数据,这些情况下,升级后表中的所有数据都将被清除:

  • 添加了一个带有 unique = true 注解的字段(因为旧的数据的这个字段的值不满足 unique 条件)
  • 为一个已存在的字段添加了 unique = true 注解(同样是因为旧的数据的这个字段的值不满足 unique 条件)
  • 为一个已存在的字段添加了 nullable = false 注解(因为旧的数据的这个字段的值不满足非 nullable 条件)

一定要注意,进行上述操作会导致数据丢失!

保存数据

所有继承自LitePalSupport的model都有save()方法用于保存数据到数据库:

Album album = new Album();
album.setName("album");
album.setPrice(10.99f);
album.setCover(getCoverImageBytes());
album.save();

更新数据

最简单的方法是使用 save 方法更新 find 找到的记录:

Album albumToUpdate = LitePal.find(Album.class, 1); //3.0.0之前是通过 DataSupport 查找的
albumToUpdate.setPrice(20.99f); //更改 price
albumToUpdate.save();

从LitePalSupport 继承的每个model也都具有 updateupdateAll 方法。 您可以通过指定 ID 更新单个记录:

Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f);
albumToUpdate.update(id);

你也可以通过使用 where 语句一次更新多条数据:

Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f);
albumToUpdate.updateAll("name = ?", "album");

删除数据

LitePal.delete(Song.class, id); //删除一条数据
DataSupport.deleteAll(Song.class, "duration > ?" , "350"); //删除多条数据

查找数据

Song song = LitePal.find(Song.class, id); //通过id查找单条数据
List<Song> allSongs = LitePal.findAll(Song.class); //查找全部数据
List<Song> songs = LitePal.where("name like ? and duration < ?", "song%", "200") //条件查询
.order("duration")
.find(Song.class);

异步操作

默认情况下,每个数据库操作都在主线程上,如果您的操作可能花费很长时间,例如保存或查询大量记录,您可能希望使用异步操作。LitePal支持所有crud方法的异步操作。

例如在后台线程中异步查找song表中的所有记录:

LitePal.findAllAsync(Song.class).listen(new FindMultiCallback<Song>() {
@Override
public void onFinish(List<Song> t) {
//异步返回查询结果
}
});

在后台线程中异步保存数据:

album.saveAsync().listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
//异步返回保存结果
}
});

多库操作(动态创建数据库)

如果您的应用需要多个数据库,LitePal会完全支持它。您可以在运行时创建任意数量的数据库。例如:

LitePalDB litePalDB = new LitePalDB("demo2", 1);
litePalDB.addClassName(Singer.class.getName());
litePalDB.addClassName(Album.class.getName());
litePalDB.addClassName(Song.class.getName());
LitePal.use(litePalDB);

这将创建一个包含 singer, album 和 song 表的名为 demo2 的数据库。

创建一个配置与 litepal.xml 相同的新的数据库:LitePal.use(LitePalDB.fromDefault("newdb"));

切换回默认数据库:LitePal.useDefault();

通过数据库名称删除数据库LitePal.deleteDatabase("newdb");

监听数据库的创建和更新

LitePal.registerDatabaseListener(new DatabaseListener() {
@Override
public void onCreate() {
// fill some initial data
} @Override
public void onUpgrade(int oldVersion, int newVersion) {
// upgrade data in db
}
});

混淆

如果您要在项目中启用ProGuard,您需要添加以下内容:

-keep class org.litepal.** {
*;
} -keep class * extends org.litepal.crud.DataSupport {
*;
} -keep class * extends org.litepal.crud.LitePalSupport {
*;
}

测试demo

实体类

public class Album extends LitePalSupport {
@Column(unique = true, defaultValue = "包青天")
private String name; private int age;//新增一个字段时需要更改数据库版本,否则操作数据时会失败
private float price; @Column(ignore = true)//忽略掉的字段,此字段的值不会保存到数据库中
private int size; //必须有一个默认的、public的无参构造器,否则执行 update 等语句时会崩溃
public Album() {
}
//省略了 set/get 方法,以及我添加的 Build 相关的代码
}

测试类

public class LitePalActivity extends ListActivity {

    protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"findAll()",
"save() ",
"find() 和 save()",
"update()",
"updateAll()",
"delete() 和 deleteAll()",
"fluent query",
"Async operations: saveAsync() + listen()",
"Async operations: findAllAsync() + listen()",
};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(array)));
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
int random = new Random().nextInt(5);
switch (position) {
case 0: //findAll()
showTips(new Gson().toJson(LitePal.findAll(Album.class))); //[{"age":1,"name":"包青天1","price":1.0,"size":0,"baseObjId":1}]
break;
case 1: //save()
Album saveAlbum = Album.newBuilder().name("包青天" + random).age(random).price(random).size(random).build();
showTips(saveAlbum.save() + " " + new Gson().toJson(saveAlbum));
break;
case 2: //find() 和 save() 和 findAll
Album findAlbum = LitePal.find(Album.class, random);
if (findAlbum != null) {
findAlbum.setPrice(9.99f); //仅更改指定的值
showTips(random + " " + findAlbum.save());
} else {
showTips("没有找到id=" + random + "的数据");
}
break;
case 3: //update()
Album updateAlbum = Album.newBuilder().name("包青天0").age(random + 100).build();
//注意:如果指定为 unique 字段的值已存在,则会报 DataSupportException: UNIQUE constraint failed: album.name
try {
int rowsAffected = updateAlbum.update(random); //未指定的字段的值不会更改,比如这里不会更改 price的值
showTips(random + " 更新" + (rowsAffected == 0 ? "失败(未找到指定 id 的数据)" : rowsAffected + "条"));
} catch (Exception e) {
e.printStackTrace();
showTips(random + " 更新失败(主键冲突 UNIQUE constraint failed )");
}
break;
case 4: //updateAll()
Album whereAlbum = Album.newBuilder().age(random + 200).price(random + 200).size(random + 200).build();
int rowsAffected = whereAlbum.updateAll("name like ? and age > ?", "包青天%", Integer.toString(3));
showTips(random + " 更新" + (rowsAffected == 0 ? "失败(未找到指定 id 的数据)" : rowsAffected + "条"));
break;
case 5://delete() 和 deleteAll()
int rowsAffected1 = LitePal.delete(Album.class, random);
int rowsAffected2 = LitePal.deleteAll(Album.class, "age < ?", Integer.toString(200));
showTips(random + " " + rowsAffected1 + " " + rowsAffected2);
break;
case 6: //fluent query
List<Album> albumList = LitePal.where("name like ? and price <= ?", "包青天%", Float.toString(3.0f))
.order("name")
.find(Album.class);
showTips(new Gson().toJson(albumList));
break;
case 7: //Async operations: saveAsync() + listen()
Album saveAsyncAlbum = Album.newBuilder().name("包青天" + random).age(random).price(random).size(random).build();
saveAsyncAlbum.saveAsync()
.listen(success -> showTips(random + "," + success + "," + (Looper.myLooper() == Looper.getMainLooper())));//主线程
break;
case 8: //Async operations: findAllAsync() + listen()
LitePal.findAllAsync(Album.class)
.listen(list -> showTips(new Gson().toJson(list)));
break;
}
} private void showTips(String s) {
Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
Log.i("bqt", s);
}
}

2018-5-28

ORM数据库框架 LitePal SQLite MD的更多相关文章

  1. ORM数据库框架 greenDAO SQLite MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. ORM数据库框架 SQLite 常用数据库框架比较 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. ORM数据库框架 SQLite ORMLite MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. SQlite数据库框架:LitePal

    常用的数据库框架Android的发展的速度是难以置信的,Android出来哪一年我还在小学上学很,还能很清楚的记得,那年一切,但是那个时候的我怎么可能也不会想到自己将来会要去做Android.Andr ...

  5. Android开源库--ActiveAndroid(active record模式的ORM数据库框架)

    Github地址:https://github.com/pardom/ActiveAndroid 前言 我一般在Android开发中,几乎用不到SQLlite,因为一些小数据就直接使用Preferen ...

  6. android高效ORM数据库框架greenDao使用

    因为项目中多处用到了数据库,需要对数据库频繁的读写操作,虽然android 自带的SQLiteOpenHelper的.这种方式比较方便易懂,但是在使用过程中需要写很多的sql语句,而且需要及时的关闭和 ...

  7. 数据库框架 Litepal

    1.导包 dependencies {   compile 'org.litepal.android:core:1.4.1' } 2.在asstes中建立litepal.xml文件 <?xml ...

  8. LitePal——Android数据库框架完整使用手册

    LitePal for Android LitePal是一个开源的Android库,使开发人员使用SQLite数据库非常简单.您无需编写任何SQL语句就可以完成大部分数据库操作,包括创建或升级表,增. ...

  9. Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite

    Android数据库框架--GreenDao轻量级的对象关系映射框架,永久告别sqlite 前不久,我在写了ORMLite这个框架的博文 Android数据库框架--ORMLite轻量级的对象关系映射 ...

随机推荐

  1. Slickflow.NET 开源工作流引擎基础介绍(八) -- 自动化任务调度实现介绍

    前言:审批流程中常见的都是人工类型任务,但是也会有一些自动化的任务需要定时触发.因此,引擎框架中需要解决掉两个问题:选择合适的任务调度框架,集成新的任务调度模块. 1. 任务调度框架选择 Hangfi ...

  2. j.u.c系列(05)---之重入锁:ReentrantLock

    写在前面 ReentrantLock,可重入锁,是一种递归无阻塞的同步机制.它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大.灵活的锁机 ...

  3. Python包管理工具pip安装

    Python版本在2.7.9+以上的都自带pip无需安装,但在CentOS 7里面自带的Python是2.7.5,所以需要单独安装. 安装: curl https://bootstrap.pypa.i ...

  4. rsync使用ssh指定端口

    增加以下参数: -e 'ssh -p 2222'

  5. RSS介绍、RSS 2.0规范说明和示例代码

    RSS是一种消息来源格式规范,用以发布经常更新资料的网站,例如博客.新闻的网摘.RSS文件,又称做摘要.网摘.更新.频道等,包含了全文或节选文字,再加上一定的属性数据.RSS让发布者自动发布信息,也使 ...

  6. Go 导入当前项目下的包

    其实和其他语言很类似 import (     "../controllers" //这里就是导入上一级目录中的controllers     "./models&quo ...

  7. layer.confirm 询问框 的层遮盖

    function admin_del(obj) { layer.confirm('确认要重启吗?', { btn : [ '确定', '取消' ]//按钮 }, function(index) { l ...

  8. 【优化】COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)等

    http://blog.itpub.net/26736162/viewspace-2136339/

  9. 3.13. Notepad++中Windows,Unix,Mac三种格式之间的转换

    由于历史原因,导致Windows,Unix/Linux,Mac三者之间,对于文件中所用回车换行符,表示的方法,都不一样. 这就导致了很多人都会遇到回车换行符的困惑,和需要在不同格式间进行转换. 其中, ...

  10. Linux线程优先级

    转自:https://www.cnblogs.com/imapla/p/4234258.html Linux内核的三种调度策略: 1.SCHED_OTHER 分时调度策略 2.SCHED_FIFO   ...