【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文件,并编辑修改为以下代码:

<?xml version="1.0" encoding="utf-8"?>                                        

将加密数据库存储在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 pricealbumToUpdate.save();

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

Album albumToUpdate = new Album();albumToUpdate.setPrice(20.99f); // raise the pricealbumToUpdate.update(id);

或者带有where条件的更新多条记录。

Album albumToUpdate = new Album();albumToUpdate.setPrice(20.99f); // raise the pricealbumToUpdate.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开发用于混淆最终的项目,增加项目被反编译的难度。

更多相关文章

  1. Android下调用jni时进行的转码操作实例
  2. android canvas 绘制bitmap并保存到本地
  3. android中重要知识点
  4. Android(安卓)高效加载大图片避免OOM
  5. Python 通过脚本获取Android的apk的部分属性,再通过加密算法生成
  6. android中基本的加密方法
  7. Activiy或者Fragment 销毁时,Dialog 的正确Dismiss方式和测试方法
  8. 【Tech-Android-View】Android4.0的横竖屏变动
  9. Android获取目录

随机推荐

  1. [置顶] Android性能分析——Activity启动
  2. Android(二)数据存储和访问 之文件
  3. Android(安卓)Studio—— jni初体验(一)
  4. android style(样式)和theme(主题)设置
  5. Android资源文件分析
  6. Android提权原理
  7. Android-线程笔记
  8. Activity的生命周期,状态保存,窗口显示,取得
  9. Android(安卓)事件传递机制实测
  10. Android(安卓)Task: