【Android】LitePal安装和使用

【Android】LitePal安装和使用

本文基本上为整理稿。感谢LitePal的作者和郭霖大神。

参考文献:

Github — https://github.com/LitePalFramework/LitePal

《LitePal 1.6.0版本来袭,数据加解密功能保障你的应用数据安全》— https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA%3D%3D&mid=2650240766&idx=1&sn=096f029aa531d5d99191c3d4c9126fc1#wechat_redirect

Tag:ORMAndroidLitePal

[TOC]

关于LitePal

LitePal是一个可以让开发者更简单操作SQLite的开源Android库。你不用写SQL命令就可以完成大部分诸如创建或更新表、CRUD操作和聚合函数等数据库操作。LitePal的安装也十分简单,不用5分钟就可以集成到你的项目中。

特性

  • 使用对象关系映射(ORM)设计模式;
  • 几乎零配置(仅仅配置一个很少属性的配置文件);
  • 自动维护所有的表(比如:创建表、修改表和删除表);
  • 多数据库支持;
  • 为避免写SQL语句而封装了APIs;
  • 极为流畅的查询API;
  • 仍然还可以选择使用SQL,但APIs要比原生的更好更容易。

安装

导入库

在AndroidStudio中,编辑build.gradle文件,加入以下:

dependencies {
    compile 'org.litepal.android:core:1.6.0'
}

配置litepal.xml

在项目中的assets文件下,创建并命名一个litepal.xml文件,并编辑修改为以下代码:



    
    

    
    

    
    
    
    
    
    

将加密数据库存储在SD卡

如果需要将加密后的数据库保存到SD卡上,则需要修改litepal.xml中的配置。代码如下:


    
    


注意:不需要填写SD卡的完成路径,需要配置相对路径即可。

由于LitePal中既没有Activity也没有Fragment,所以LitePal是不会去帮你申请运行时的SD卡访问读写权限。如果选择将数据库文件存储在SD卡上,请一定要确保你的应用程序已经对访问SD卡权限进行了运行时权限处理,否则LitePal的所有操作都将会失败。

配置LitePalApplication

配置AndroidManifest.xml如下:


    

    

当然,还有一种配置方法。


    
    

public class MyOwnApplication extends xxxApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        LitePal.initialize(this);
    }
    
}

注意:最好是在onCreate()方法中进行初始化LitePal.initialize(this)

使用

创建表

比如,有两个模型类:【专辑】和【歌曲】。定义模型如下:

public class Album extends DataSupport {
    
    @Column(unique = true, defaultValue = "unknown")
    private String name;
    
    private float price;
    
    private byte[] cover;
    
    private List songs = new ArrayList();

    // generated getters and setters.
   
}
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文件中添加这两个模型的映射列表。


    
    

这样,当进行数据库操作的时候,会自动生成表。例如:

SQLiteDatabase db = LitePal.getDatabase();

自动生成的表,等价于以下SQLs:

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
);

更新表

例如添加一个发布时间字段并注释掉【售价】字段:

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 songs = new ArrayList();

    // generated getters and setters.
    
}

litepal.xml文件中的数据库版本会自动进行更新。



保存数据

保存操作的API是面向对象的。每个继承于DataSupport的模型都有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();

更新数据

最简单的方法,通过find()找到记录,并使用save()方法更新记录。

Album albumToUpdate = DataSupport.find(Album.class, 1);
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.save();

每个继承于DataSupport的模型,都有update()updateAll()方法。

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");

删除数据

使用DataSupport中静态方法delete()删除一条记录。

DataSupport.delete(Song.class, id);

或者使用DataSupport中静态方法deleteAll()删除多条记录。

DataSupport.deleteAll(Song.class, "duration > ?" , "350");

查询数据

从【歌曲】表中通过id查找单一条记录。

Song song = DataSupport.find(Song.class, id);

从【歌曲】表中查找多条记录。

List allSongs = DataSupport.findAll(Song.class);

通过fluent query构建复杂查询。

List songs = DataSupport.where("name like ?", "song%").order("duration").find(Song.class);

异步操作

默认每个数据库操作都是在主线程上。如果操作可能花费很长的时间,例如保存或者查询大量的记录,可能需要使用异动操作。

LitePal的所有CRUD方法都支持异步操作。例如,在后台线程从【歌曲】表中查找多条记录,代码如下:

DataSupport.findAllAsync(Song.class).listen(new FindMultiCallback() {
    @Override
    public  void onFinish(List t) {
        List allSongs = (List) 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(),并且拓展一个listen()方法,当在后台将【专辑】存储到数据库后,通过回调onFinish()方法返回存储结果。

多数据库

如果App需要多个数据库,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);

上面这段代码是创建一个demo2的数据库,里面有【歌手】、【专辑】和【歌曲】三张表。

如果你只是想创建一个新的数据库,而不想配置litepal.xml,你可以参照如下:

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

你可以通过下面的操作切换回默认数据库。

LitePal.useDefault();

你也可以通过表名删除任何数据库。

LitePal.deleteDatabase("newdb");

字符串加密

从1.6.0版本LitePal内置了对数据(字符串)进行AES或者MD5加解密的功能。

AES:全称是Advanced Encryption Standard,中文名叫高级加密标准,同时它也是美国联邦政府采用的一种区块加密标准。

MD5:全称是Message Digest Algorithm 5,中文名叫信息摘要算法第五版。要说到MD5加密算法的特点其实有很多很多,但是它最为突出的一个特点就是,使用这种加密算法计算出来的结果是不可逆的。通俗点来说,就是MD5算法只能进行加密但不能进行解密。

AES

一个书本类,类中有一个【书名】属性和一个【页数】属性,现在将【书名】属性的值进行加密,只需要在【书名】属性的上方加上@Encrypt(algorithm = AES)这样一行注解即可代码如下:

public class Book extends DataSupport {
    @Encrypt(algorithm = AES)
    private String name;
    private int page;
    
    // getter and setter
}

对于开发者而言,加解密操作是完全透明化的。也就是说,作为开发者并不用考虑某个字段有没有被加密,然后要不要进行解密等等,我们只需要仍然使用标准的LitePal API来查询数据即可。

比如从书本表中查询这条数据,并打印。

Book book = DataSupport.findFirst(Book.class);
String name = book.getName();
int page = book.getPage();
Log.d(TAG, "book name is " + name);
Log.d(TAG, "book page is " + page);

细节

  • 可以自定义AES算法的密钥。如果没有指定密钥,LitePal会使用默认的密钥进行加解密。使用LitePal.Key()方法来自定义密钥;

  • AES算法和MD5算法都只对String类型的字段有效,如果你尝试给其他类型的字段(比如说int字段)指定@Encrypt注解,LitePal并不会执行任何加密操作;

  • 加密后的数据字段不能再通过where语句来进行查询、修改或删除。

    也就是说,执行类似于 where("name = ?", "第一行代码") 这样的语句将无法查到任何数据,因为在数据库中存储的真实值已经不是"第一行代码"了。

MD5

与AES类似,加密基本是一模一样的用法,我们只需要将@Encrypt中指定的加密算法改成MD5即可。

public class User extends DataSupport {
    @Encrypt(algorithm = MD5)
    private String password;
    private String username;
    
    // getter and setter
}

代码混淆

如果你需要使用Proguard,可能需要添加以下代码到项目文件中。

-keep class org.litepal.** {
    *;
}

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

ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、方法和属性。常常用于Android开发用于混淆最终的项目,增加项目被反编译的难度。

你可能感兴趣的:(【Android】LitePal安装和使用)