Android持久化存储(4)greenDAO的使用

1.背景

在上篇博客介绍SQLite的使用我们能感觉到,虽然Android已经简化了一些SQLite的操作,提供了较为方便的API,但使用中还是需要开发者写一些SQL语言,简单而不简约,有时候只想存储一些简单数据,却需要花费很大力气去开发接口,当然你可以说让另一个程序员去开发数据库操作接口不就行了吗,你老板肯定不同意,这么简单的活还要找别人,本来招你就是想一个人当两个人用,你还奢望一份工作两个人干?!如果你为这个事发愁,那赶紧来看看今天要介绍的greenDAO。

2.什么是GreenDAO

greenDAO官网关于greenDAO的介绍直击开发者痛点—摆脱编写SQL的泥沼!如果觉得这个slogan还不是很清楚,可以看一下详细的介绍:

greenDAO是一个开放源代码的Android ORM,令开发SQLite数据库变得更有趣。它使开发人员免于陷入处理低级数据库泥沼,节省了开发时间。 SQLite是一个很棒的嵌入式关系数据库,然而编写SQL和解析查询结果仍然是非常繁琐且耗时的任务。通过将Java对象映射到数据库表(称为ORM,“对象/关系映射”),greenDAO使您摆脱这些麻烦。这样,您可以使用简单的面向对象的API来存储,更新,删除和查询Java对象。

greenDAO具有如下优势

  • 高性能,可能是最快的Android ORM(虽然有可能违法广告法,但确实疗效不错);
  • 易于使用的强大API;
  • 内存消耗小;
  • 库体积小;(<100KB);
  • 支持数据库加密:greenDAO支持SQLCipher,以确保用户数据的安全

greenDAO如何做到简化数据库操作呢?因为使用了ORM,即对象关系映射(Object Relational Mapping),对象指业务实体对象(这里指java对象),关系指关系型数据库,通过将关系型数据库和业务实体对象之间作一个映射,开发人员只和对象打交道,不用面对繁琐的SQL语言,对象到数据库的映射由中间件帮忙映射,greenDAO正是扮演这样的角色。
在这里插入图片描述

3.greenDAO的使用

3.1 工程中添加greenDAO

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xqm6OaGd-1584092039668)(./assets/在哪里买到呢.jpg)]
greenDAO如此方便,那么在哪里下载到呢?又如何添加到工程中呢?在工程中配置很简单,只需要配置两个build.gradle文件,首先是工程根目录下的build.gradle,第一步是在仓库repositories里添加mavenCentral,因为greenDAO放在Maven Central上,第二步是在依赖dependencies中添加greenDAO,请注意使用最新版本,可在这个网址查询版本号。

buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral()
        
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.2'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' //
    }
}

第二个要修改的build.gradle是应用目录下的app/build.gradle,首先是声明使用greenDAO,其次是配置greenDAO选项,最后在依赖中添加greenDAO。

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' 

android {
...
}
//在这里设置greenDAO的配置选项
greendao {
    schemaVersion 2
    daoPackage "com.test.greendaodemo" 
}

//build.gradle里的依赖模块
dependencies {
    implementation 'org.greenrobot:greendao:3.2.2' 
}

其中,greenDAO里配置支持多个属性配置,分别如下:

  • schemaVersion: 数据库的当前版本。如果更改实体/数据库架构,则必须增加该值,如果不配置该选项,则数据库版本默认为1;
  • daoPackage: 生成的DAO,DaoMaster和DaoSession的程序包名称。默认为实体所在的程序包名;
  • targetGenDir: 生成代码的存储位置。 默认是build目录下(build / generated / source / greendao);
  • generateTests: 设置成true以自动生成单元测试;
  • targetGenDirTests: 生成的单元测试存储目录。默认为src / androidTest/java。

配置完两处gradle之后,程序中便可以开始使用greenDAO了。

3.2 创建实体类

例如我们创建一个Book的实体类,这一步类似于创建数据库的表,只不过这里操作的是对象。Book实体类的代码如下,这个实体类就是一般的java代码,还不能和数据库进行映射,为了用上greenDAO,还需要对这个实体类进行注解,或者说打上标记,实现很简单,在class上使用@Entity即可,这样就变成greenDAO可识别的实体类(没看过greenDAO源代码,猜测greenDAO会扫描所有代码文件,发现了这个标记识别成要映射的实体类)。

我们在创建数据库的表时,对每一列的要求可能不一样,例如想把某一列设置成自增长,某一列值不能为空等,实体类是不是也可以这么设置呢,答案是可以,想设置哪个变量(或者说是哪一列,因为实体类中的变量会转换成数据库的列名),在该变量声明上打上标记就像,例如想设置id为自增长主键,那就在id之上添加@Id(autoincrement = true)注意,greenDAO要求主键必须是long类型),要设置ISBN为非空列,那就添加注解@NotNull,或者想把某个变量排除在外,不写入数据表,那就添加注解@Transient。Book实体类完整示例如下

package com.test.greendaodemo;

import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.NotNull;
import org.greenrobot.greendao.annotation.Transient;
import org.greenrobot.greendao.annotation.Generated;

@Entity
public class Book {
    @Id(autoincrement = true)
    private long id;
    private String name;//书名
    @NotNull
    private long ISBN;//国际标准书号
    private String author;//作者
    private float price;//价格
    @Transient
    private String press;//出版社


    @Generated(hash = 1424927682)
    public Book(long id, String name, long ISBN, String author, float price) {
        this.id = id;
        this.name = name;
        this.ISBN = ISBN;
        this.author = author;
        this.price = price;
    }

    @Generated(hash = 1839243756)
    public Book() {
    }


    //getter setter
    public long getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getISBN() {
        return ISBN;
    }

    public void setISBN(long ISBN) {
        this.ISBN = ISBN;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }

    public void setId(long id) {
        this.id = id;
    }
}

实体类设置完之后,点击make project,greenDAO便根据这个实体类自动生成BookDao,DaoMasterDaoSession三个文件,因为没在app/build.gradle里设置greendao的targetGenDir,因此生成的三个文件路径放在默认路径build/source/greendao下。如果想放置到java代码目录下,设置targetGenDir成指定目录即可。个人建议使用默认地址,因为这是自动生成的代码,不需要开发者去修改,如果放在java目录下,不了解greenDAO的开发人员误认为是人工写的代码,反而可能去修改其中的代码导致出错。
在这里插入图片描述
虽然是自动生成的代码,但还是需要了解一下生成的这个代码文件是做啥的。

  • DaoMaster:点击打开DaoMaster,可以看到代码封装了SQLiteDatabase和SQLiteOpenHelper(DatabaseOpenHelper继承了SQLiteOpenHelper),这表示DaoMaster功能是创建和升级SQLite数据库,也是使用greenDAO的入口;
  • BookDAO:对于每个实体,greenDAO生成对应的DAO,因示例代码只创建了Book实体,故只生成了BookDAO,一般是名字为xxx的实体,会生成的DAO是xxxDAO,DAOs里包括根据实体创建表的方法,读取等方法;
  • DaoSession:这个类管理所有可用DAO对象,例如示例中的BookDao,可通过使用getter方法获取该对象。

这三个文件又有怎样的关系呢,DaoMaster是入口,通过其获得DaoSession,而DaoSession又管理着所有DAO,因此可以通过DaoSession获得DAO对象,他们的关系图如下图所示,我们将会在实际使用的时候再理解一下他们的关系。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2eqc1yr7-1584092039669)(assets/Core-Classes-150.png)]

3.3 greenDAO初始化

创建一个application类,然后在application中完成DaoSession的初始化,这样的好处是依托于Application单例模式,可避免以后重复初始化greenDAO,代码如下,别忘了在AndroidManifest.xml里增加android:name=".MyApplication"

package com.test.greendaodemo;

import android.app.Application;
import android.database.sqlite.SQLiteDatabase;

public class MyApplication extends Application {
    private DaoMaster.DevOpenHelper mHelper;
    private SQLiteDatabase db;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    public static MyApplication instances;
    @Override    public void onCreate() {
        super.onCreate();
        instances = this;
        setDatabase();
    }
    public static MyApplication getInstances(){
        return instances;
    }

    /**
     * 设置greenDao
     */
    private void setDatabase() {
        // 通过 DaoMaster的内部类DevOpenHelper可获得SQLiteOpenHelper对象。
        mHelper = new DaoMaster.DevOpenHelper(this, "greenDAOdemo_db", null);
        db = mHelper.getWritableDatabase();
        mDaoMaster = new DaoMaster(db);
        mDaoSession = mDaoMaster.newSession();
    }
    public DaoSession getDaoSession() {
        return mDaoSession;
    }
    public SQLiteDatabase getDb() {
        return db;
    }
}

3.4 使用greenDAO实现增删改查

实现增删改查需要获取DAO对象,如何取得DAO对象呢?回忆一下上边提到的greenDAO生成的三个文件关系图,还有印象的话,可知道获取DAO对象需要通过DaoSession,而获取DaoSession又是通过DaoMaster。有了DAO对象,可很方便的实现增删改查,基本上只需要实例化Book对象,配置Book对象各个属性的值,再使用BookDao对应的增删改查方法就能简单快速执行对应的操作,示例代码如下,从示例代码可以看到,增删改查全程没见到烦人的SQL语句,因为greenDAO替我们去生成和执行对应的SQL语句了。

BookDao mbookdao = MyApplication.getInstances().getDaoSession().getBookDao();
        //增
        book = new Book();
        book.setId((long)2);
        book.setName("三体");
        book.setISBN((long)89327455);
        book.setAuthor("刘慈欣");
        book.setPrice((float)50.00);
        book.setPress("重庆出版社");
        mbookdao.insert(book);

        //删
        mbookdao.deleteByKey((long)1);

        //改
        book.setPrice((float)30.00);
        mbookdao.update(book);

        //查
        List<Book> booklist = mbookdao.loadAll();
        String bookname = "";
        StringBuilder stringBuilder=new StringBuilder();
        for (int i = 0; i < booklist.size(); i++) {

            bookname += booklist.get(i).getName()+",";
            stringBuilder.append(booklist.get(i).getId()+"\n");
            stringBuilder.append(booklist.get(i).getName()+"\n");
            stringBuilder.append(booklist.get(i).getAuthor()+"\n");
            stringBuilder.append(booklist.get(i).getISBN()+"\n");
            stringBuilder.append(booklist.get(i).getPress()+"\n");

        }

4.总结

greenDAO通过ORM方案,将实体类和数据库映射,避免程序员直接面对SQL语言,大大简化了SQLite数据库开发流程,如果只是简单的数据库存储操作,大可借助greenDAO来开发,因为greenDAO使用简单,配置简单,占用内存小,处理速度快,而且还是开源的,有好的轮子先用着吧,先把老板安排的工作做好,待到实力大增还有时间,再想办法自己造轮子或者优化轮子,这是后话了。

发布了19 篇原创文章 · 获赞 6 · 访问量 6438

猜你喜欢

转载自blog.csdn.net/lansoul1987/article/details/104845696
今日推荐