1. 导入库
编辑build.gradle文件并添加以下依赖说明:
dependencies {
implementation 'org.litepal.android:core:2.0.0'
}
2. 配置litepal.xml
在工程里的assets文件夹里新建一个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 automaticly for you.
For example:
<dbname value="demo" ></dbname>
-->
<dbname value="demo" ></dbname>
<!--
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 automaticly without concern.
For example:
<version value="1" ></version>
-->
<version value="1" ></version>
<!--
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>
<mapping class="com.test.model.Magazine"></mapping>
</list>
-->
<list>
</list>
</litepal>
这是唯一的一个配置文件,里面的属性很简单。
3. 配置LitePalApplication
操作数据库时需要使用到Context参数,我们不想每次都传递这个参数,那么只需要在AndroidManifest.xml中配置下LitePalApplication即可,如下:
<manifest>
<application
android:name="org.litepal.LitePalApplication"
...
>
...
</application>
</manifest>
当然,你可能有自己的Application并且已经配置好,如下:
<manifest>
<application
android:name="com.example.MyOwnApplication"
...
>
...
</application>
</manifest>
没关系,只需要将MyOwnApplication由原来的继承Application类改成继承LitePalApplication类就可以,如下:
public class MyOwnApplication extends LitePalApplication {
...
}
如果你的MyOwnApplication必须继承另外的Application类,如AnotherApplication类,那么你可以直接调用LitePalApplication.initialize(context)而无需继承LiteApplication类,如下:
public class MyOwnApplication extends AnotherApplication {
@Override
public void onCreate() {
super.onCreate();
LitePalApplication.initialize(this);
}
...
}
LitePalApplication.initialize(context)的调用原则是尽可能早,比如合适的调用位置是在Application的onCreate()里调用。调用时传递的参数是Application的context,不要使用任何activity或service的实例作为参数,否则可能发生内存泄漏。
开始LitePal体验之旅
1. 创建表格
首先定义各种model,比如有两个model:Album和Song,定义如下:
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.
...
}
将这两个model添加到litepal.xml的映射表中,如下:
<list>
<mapping class="org.litepal.litepalsample.model.Album" />
<mapping class="org.litepal.litepalsample.model.Song" />
</list>
一旦操作数据库时,数据库表格将自动生成。比如使用以下代码获取SQLiteDatabase 时,
SQLiteDatabase db = Connector.getDatabase();
将自动生成album和song两张数据库表格,如下:
CREATE TABLE album (
id integer primary key autoincrement,
name text unique default 'unknown',
price real
);
CREATE TABLE song (
id integer primary key autoincrement,
name text not null,
duration integer,
album_id integer
);
2. 升级表格
在LitePal中实现升级表格非常容易。
public class Album extends LitePalSupport {
@Column(unique = true, defaultValue = "unknown")
private String name;
@Column(ignore = true)
private float price;
private byte[] cover;
private Date releaseDate;
private List<Song> songs = new ArrayList<Song>();
// generated getters and setters.
...
}
上述代码中,添加了releaseDate并且price标注为ignore。
<!--
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 automaticly without concern.
For example:
<version value="1" ></version>
-->
<version value="2" ></version>
只需要在litepal.xml中升级版本号,那么下次操作数据库时表格将自动升级:ablum表中添加了releasedate列,删除了price列,其他列的数据原封不动。
以下一些升级情况LitePal无法处理并且被升级表格里的所有数据将被清空:
以上情况会导致数据丢失,要格外注意。
3. 保存数据
每一个继承LitePalSupport 类的model都有save() 方法。
Album album = new Album();
album.setName("album");
album.setPrice(10.99f);
album.setCover(getCoverImageBytes());
album.save();
Song song1 = new Song();
song1.setName("song1");
song1.setDuration(320);
song1.setAlbum(album);
song1.save();
Song song2 = new Song();
song2.setName("song2");
song2.setDuration(356);
song2.setAlbum(album);
song2.save();
以上代码实现将album, song1和song2插入到数据库中并建议关联。
4. 更新数据
最简单的方法,使用save() 方法来更新由 find() 找到的记录:下:
Album albumToUpdate = LitePal.find(Album.class, 1);
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.save();
从LitePalSupport 继承的每个模型都有update() 和updateAll() )方法。可以用指定的ID更新单个记录:
Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.update(id);
或者可以用where条件更新多个记录:
Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.updateAll("name = ?", "album");
5. 删除数据
调用LitePal 的静态方法delete() 可删除指定id的单条记录:
LitePal.delete(Song.class, id);
也可调用LitePal 的静态方法deleteAll() 删除多条记录:
LitePal.deleteAll(Song.class, "duration > ?" , "350");
6. 查询数据
查询song表中指定id的单条记录:
Song song = LitePal.find(Song.class, id);
查询song表中的所有记录:
List<Song> allSongs = LitePal.findAll(Song.class);
构建复杂的集群查询:
List<Song> songs = LitePal.where("name like ? and duration < ?", "song%", "200").order("duration").find(Song.class);
7. 异步操作
默认情况下,每个数据库操作都在主线程上。如果你的操作可能花很长时间,例如保存或查询大量的记录,你可能希望使用异步操作。
LitePal支持所有的CRUD方法的异步操作。如果你想从后台线程中找到歌曲表中的所有记录,请使用这样的代码:
LitePal.findAllAsync(Song.class).listen(new FindMultiCallback() {
@Override
public <T> void onFinish(List<T> t) {
List<Song> allSongs = (List<Song>) t;
}
});
只需要使用 findAllAsync()替代 findAll(), 并使用 listen() 方法,找到的结果将在完成后回调到onFinish()方法中.
异步保存也是同样的:
Album album = new Album();
album.setName("album");
album.setPrice(10.99f);
album.setCover(getCoverImageBytes());
album.saveAsync().listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
}
});
仅需要使用 saveAsync() 替代 save(). 保存记录的数据将在后台完成, 并将保存结果返回到 onFinish() 方法。