Android LitePal让数据库使用so easy(译)

2022-05-09 10:33:44 浏览数 (1)

飞哥语录:面向对象的精髓在于对现实世界中事物的抽象。

如果英文比较好的可以点击 此处 查看原文

LitePal是一个开源Android库,它允许开发者快速容易地使用SQLite数据库. 你可以完成大多数数据库的操作,甚至而不用写一句SQL语句, 包括创建和升级数据库表, crud(增删改查)操作, 它聚集了很多功能等等. LitePal数据库的配置也是十分的简单, 不到5分钟你就可以将它集成到你的项目中.

现在你可以愉快地开始魔幻般的体验了!

特性

  • 使用 object-relational mapping (ORM) 对象关系映射模式.
  • 几乎0配置(仅仅一个配置文件就可以配置好几种属性).
  • 自动维护所有表(例如创建、修改和更新表).
  • 支持复杂的数据库.
  • 封装了APIs为了避免书写SQL语句.
  • 极好流畅的查询API.
  • 你任然可以选择使用SQL语句, 但是使用它封装好的APIs要比原生的更好和更容易.
  • 更多可以请往下浏览.

最新jar包&源码下载

  • litepal-1.4.1.jar (library contains *.class files)
  • litepal-1.4.1-src.jar (library contains *.class files and *.java files)

快速设置

1. 引入库
使用Eclipse
  • 在上一个段中下载最新的jar包.或者浏览所有的版本 点击浏览 选择一个去下载.
  • 把jar包拷贝进到你工程的 libs目录.
使用Android Studio开发

编辑你的 build.gradle 文件并且添加以下依赖:

代码语言:javascript复制
    compile 'org.litepal.android:core:1.4.1'
2. 配置 litepal.xml文件

在你的工程中创建一个assets 目录,在此目录下新建一个名为 litepal.xml文件. 然后把下面的代码拷贝进去.

代码语言:javascript复制
	<?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 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 automaticly 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>

这仅仅只是配置文件, 这个配置也是非常简单.

  • dbname 配置你的工程的数据库名称.
  • version 配置数据库版本号. 每次你想升级数据库, 就将这个值 1.
  • list 配置映射的JavaBean类.
  • storage 配置你的数据库将会保存在哪里. internalexternal 只有这两种合法的选择.
3. 配置LitePalApplication

如果你想要总是传递Context参数. 为了使APIs简单, 只要配置LitePalApplication在AndroidManifest.xml文件中配置如下即可:

代码语言:javascript复制
	<manifest>
	<application
		android:name="org.litepal.LitePalApplication"
		...
	>
    ...
	</application>
</manifest>

当然你也可以使用你自己已有的Application里去配置,例如:

代码语言:javascript复制
<manifest>
	<application
		android:name="com.example.MyOwnApplication"
		...
	>
    ...
	</application>
</manifest>

好了. LitePal可以活跃起来了. 只要在你的Application调用 LitePal.initialize(context) 就好了 :

代码语言:javascript复制
public class MyOwnApplication extends AnotherApplication {  
	@Override
	public void onCreate() {
		super.onCreate();
		LitePal.initialize(this);
	}
}

尽可能早的在你的Application的**onCreate()**方法里去调用这个. 并且总是记得去使用application context参数. 不要去使用activity 或者 service的实例作为参数, 否则会导致内存泄漏问题.

我们继续

设置完之后, 现在你可尽情地体验它的强大之处了.

1. 创建表

首先定义models. 假设你有两个models, AlbumSong. 他们的定义如下:

代码语言:javascript复制
public class Album extends DataSupport {
	
	@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.
	...
}
代码语言:javascript复制
public class Song extends DataSupport {
	
	@Column(nullable = false)
	private String name;
	
	private int duration;
	
	@Column(ignore = true)
	private String uselessField;
	
	private Album album;

	// generated getters and setters.
	...
}

然后在litepal.xml 文件的list标签内添加这2个models的全类名:

代码语言:javascript复制
<list>
    <mapping class="org.litepal.litepalsample.model.Album"></mapping>
    <mapping class="org.litepal.litepalsample.model.Song"></mapping>
</list>

好了! 下次你操作数据库的时候这些表就会生成. 例如, 使用下面的代码SQLiteDatabase来获取数据库实例:

代码语言:javascript复制
SQLiteDatabase db = LitePal.getDatabase();

现在这些表会自动的生成,对应的SQLs语句如下:

代码语言:javascript复制
CREATE TABLE album (
	id integer primary key autoincrement,
	name text unique default 'unknown',
	price real,
	cover blob
);

CREATE TABLE song (
	id integer primary key autoincrement,
	name text not null,
	duration integer,
	album_id integer
);
2. 升级表

使用LitePal升级表是非常容易的. 只要修改你想修改的你的models的地方即可:

代码语言:javascript复制
public class Album extends DataSupport {
	
	@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 去添加一个被忽略的注释. 然后在你的 litepal.xml文件中数据库的version 1即可:

代码语言:javascript复制
<!--
    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>

下次你操作数据库的时候这些表就会被升级, 一个 releasedate 字段将会被添加到 album 表并且原来的price 字段将会被移除. 所有数据在 album 表中处理那些被移除的字段。

但是有一些升级表的情况LitePal不能处理升级表被清理的情况,例如:

  • 添加一个属性 unique = true.
  • 改变属性 unique = true.
  • 把属性变为 nullable = false.

要注意上面的这些情况将会造成数据的丢失.

3. 保存数据

保存数据API的时候有些调整. 每一个model将会继承DataSupport类,然后调用save() 方法:

代码语言:javascript复制
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()**去查找:

代码语言:javascript复制
Album albumToUpdate = DataSupport.find(Album.class, 1);
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.save();

每一个model都将继承于 DataSupport,从而这些类都会有 update()updateAll() 方法. 你可以使用具体的id来修改单个记录:

代码语言:javascript复制
Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.update(id);

或者你可以使用where条件来修改多条数据:

代码语言:javascript复制
Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.updateAll("name = ?", "album");
5. 删除数据

你可以删除单个数据使用DataSupport里的静态方法 delete():

代码语言:javascript复制
DataSupport.delete(Song.class, id);

或者删除多条数据使用DataSupport里的静态方法deleteAll() :

代码语言:javascript复制
DataSupport.deleteAll(Song.class, "duration > ?" , "350");
6. 查询数据

使用具体的id从song表中查询一条数据:

代码语言:javascript复制
Song song = DataSupport.find(Song.class, id);

从song表中查询所有数据记录:

代码语言:javascript复制
List<Song> allSongs = DataSupport.findAll(Song.class);

流畅的查询复杂的结构:

代码语言:javascript复制
List<Song> songs = DataSupport.where("name like ?", "song%").order("duration").find(Song.class);
7. 多数据库

如果你需要创建多个数据库, LitePal也可以完全的支持. 在运行的时候你可创建尽可能多的数据库.例如:

代码语言:javascript复制
LitePalDB litePalDB = new LitePalDB("demo2", 1);
litePalDB.addClassName(Singer.class.getName());
litePalDB.addClassName(Album.class.getName());
litePalDB.addClassName(Song.class.getName());
LitePal.use(litePalDB);

这里将创建一个demo2数据库,包含singer, albumsong3个表结构.

如果你想新建一个数据库并且使用相同的配置文件litepal.xml, 你可以这样做:

代码语言:javascript复制
LitePalDB litePalDB = LitePalDB.fromDefault("newdb");
LitePal.use(litePalDB);

You can always switch back to default database with:

代码语言:javascript复制
LitePal.useDefault();

And you can delete any database by specified database name:

代码语言:javascript复制
LitePal.deleteDatabase("newdb");

Translated By

  • xpf

示例App

示例 App已经发布到了Google Play.

获取:

Bugs报告

当你在使用LitePal的时候发现bug, 请报告 here. 感谢你的帮助让我们做的更好.

版本更新日志

1.4.1

  • Fix bug of DateSupport.count error.
  • Fix bug of losing blob data when upgrading database.
  • Fix other known bugs.

1.4.0

  • Support multiple databases.
  • Support crud operations for generic collection data in models.
  • Add SQLite keywords convert function to avoid keywords conflict.
  • Fix known bugs.

1.3.2

  • Improve an outstanding speed up of querying and saving.
  • Support to store database file in external storage.
  • Support to mapping fields which inherit from superclass.
  • Add findFirst() and findLast() in fluent query.
  • Add isExist() and saveIfNotExist() method in DataSupport.

1.3.1

  • Support storing binary data. Byte array field will be mapped into database as blob type.
  • Add saveFast() method in DataSupport. If your model has no associations to handle, use saveFast() method will be much more efficient.
  • Improve query speed with optimized algorithm.

1.3.0

  • Add annotation functions to decalre unique, not null and default constraints.
  • Remove the trick of ignore mapping fields with non-private modifier.
  • Support to use annotation to ignore mapping fields with ignore = true
  • Add some magical methods in DataSupport for those who understand LitePal deeper.
  • Fix known bugs.

License

代码语言:javascript复制
Copyright (C)  Tony Green, LitePal Framework Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

本文由Vancy翻译,由于本人水平有限,如果有什么问题,希望大家批评指正。

声明: 1.本文内容归原作者所有。

0 人点赞