Android ORM框架 GreenDao 的使用详解

一、前言

关于 Android 中常用的数据存储方式我们前面已经讲了 Sp 存储和文件存储,但是对于数据量比较大,并且结构复杂的数据我们想要存储只能通过数据库进行处理,Android 中提供了一个 SQLite 数据库,但是使用起来比较繁琐和复杂,所以 Android 又推出了 Room 持久性库,Room 持久性库在 SQLite 的基础上提供了一个抽象层,让用户能够在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制。但是我们今天不讲 Room 这个组件(以后讲 Jetpack 组件的时候再讲),我们今天来讲一个开源的安卓 ORM 框架———greenDAO

二、greenDAO 概述

greenDAO 是适用于 Android 的轻量级快速 ORM 框架,可将对象映射到 SQLite 数据库中。 并且针对 Android 进行了高度的优化,greenDAO 提供了出色的性能,并占用了最少的内存,优点如下:

  • 性能上(可能是 Android 上最快的 ORM 框架);
  • 易用性上(提供强大并且简洁明了的 API);
  • 轻量(最小的内存消耗与小于 150KB 的库大小)。

三、ORM 框架概述

所谓 ORM 框架,即 Object-Relational Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体操作数据库的时候,就不需要再去和复杂的 SQL 语句打交道,只是像平时操作对象一样操作它就可以了。

四、项目案例演示

案例具体效果如下所示:


这个案例就是利用 greenDAO 对商品进行增删改查。

点击插入数据,就会把所有的数据保存到数据库中,点击查询所有数据,会将数据库中的所有数据查询出来,并显示在界面上,同时也可以根据条件进行查询,当点击查询零食类时,只会将零食查询出来显示在桌面上,点击单个商品,会跳转到商品详情页,在商品详情页可以对商品的描述进行修改,同时也可以删除商品。

商品的列表显示是用 RecyclerView 进行实现的。

五、greenDAO 使用步骤

5.1、准备工作

5.1.1、引入 greenDAO

greenDAO 的引入非常简单,我们只要按照 github 文档 上去做就可以了,具体如下所示:

5.1.2、创建实体类

@Entity
public class GoodsModel implements Parcelable {
    @Id(autoincrement = true)
    private Long id;
    @Index(unique = true)
    private Integer goodsId;
    private String name;
    private String icon;
    private String info;
    private String type;

其中 @EntitygreenDAO 的实体注解(用于标识当前实体需要 GreenDao 生成代码)。

@Id 是主键 idLong 类型,可以通过 @Id(autoincrement = true) 设置自动增长(自动增长主键不能用基本类型 long,只能用包装类型 Long)。

@Index(unique = true) 是向数据库添加了唯一约束。

5.1.3、自动生成实体类代码

写完上面实体类代码之后,接下来实体类代码的生成就交给 Android Studio 编译器就可以了,首先我们点击菜单栏中 Build 然后点击 Make Project,等待编译器编译完就可以了,编译完后实体类代码如下所示:(这里实现了 Parcelable 接口是为了在 Activity 之间传递实体类,实现接口的方法一直 Alt + Enter 就可以了)

@Entity
public class GoodsModel implements Parcelable {
    @Id(autoincrement = true)
    private Long id;
    @Index(unique = true)
    private Integer goodsId;
    private String name;
    private String icon;
    private String info;
    private String type;

    protected GoodsModel(Parcel in) {
        if (in.readByte() == 0) {
            id = null;
        } else {
            id = in.readLong();
        }
        if (in.readByte() == 0) {
            goodsId = null;
        } else {
            goodsId = in.readInt();
        }
        name = in.readString();
        icon = in.readString();
        info = in.readString();
        type = in.readString();
    }

    @Generated(hash = 1834473137)
    public GoodsModel(Long id, Integer goodsId, String name, String icon,
                      String info, String type) {
        this.id = id;
        this.goodsId = goodsId;
        this.name = name;
        this.icon = icon;
        this.info = info;
        this.type = type;
    }

    @Generated(hash = 971639536)
    public GoodsModel() {
    }

    public static final Creator CREATOR = new Creator() {
        @Override
        public GoodsModel createFromParcel(Parcel in) {
            return new GoodsModel(in);
        }

        @Override
        public GoodsModel[] newArray(int size) {
            return new GoodsModel[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        if (id == null) {
            dest.writeByte((byte) 0);
        } else {
            dest.writeByte((byte) 1);
            dest.writeLong(id);
        }
        if (goodsId == null) {
            dest.writeByte((byte) 0);
        } else {
            dest.writeByte((byte) 1);
            dest.writeInt(goodsId);
        }
        dest.writeString(name);
        dest.writeString(icon);
        dest.writeString(info);
        dest.writeString(type);
    }

    public Long getId() {
        return this.id;
    }

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

    public Integer getGoodsId() {
        return this.goodsId;
    }

    public void setGoodsId(Integer goodsId) {
        this.goodsId = goodsId;
    }

    public String getName() {
        return this.name;
    }

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

    public String getIcon() {
        return this.icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public String getInfo() {
        return this.info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String getType() {
        return this.type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

点击编译后,编译器不仅会为我们自动完成实体类代码的生成,还会在 build 目录下生成三个文件 DaoMasterDaoSessionXXXDao。利用这三个文件我们就可以操作数据库了,如下所示:

5.1.4、初始化 greenDAO

我这里是在 Application 里面初始化(注意要在清单文件里面引用,否则 Application 不生效),并提供一个getDaoSession() 的方法供外部使用,具体代码如下:

public class MyApplication extends Application {

    public static DaoSession mSession;

    @Override
    public void onCreate() {
        super.onCreate();

        initDb();
    }

    /**
     * 连接数据库并创建会话
     */
    public void initDb() {
        // 1、获取需要连接的数据库
        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "test.db");
        SQLiteDatabase db = devOpenHelper.getWritableDatabase();
        // 2、创建数据库连接
        DaoMaster daoMaster = new DaoMaster(db);
        // 3、创建数据库会话
        mSession = daoMaster.newSession();
    }
    
    // 供外接使用
    public DaoSession getDaoSession() {
        return mSession;
    }
}

5.2、具体使用(增删改查)

准备工作做完之后,使用起来就非常简单了,只需要调用 greenDAOAPI 就可以了。要想操作数据库,我们首先要获取 DAO 实例,我们创建一个 GreenDaoManager 类来专门管理数据库的操作,具体代码如下所示:

public class GreenDaoManager {

    private Context mContext;
    private GoodsModelDao mGoodsModelDao;

    public GreenDaoManager (Context context) {
        this.mContext = context;
        // 获取DAO实例
        mGoodsModelDao = MyApplication.getDaoSession().getGoodsModelDao();
    }
}

5.2.1、新增数据

// 添加一个实体
DAO.insert(T entity);
// 添加多个实体
DAO.insertInTx(T... entities);
...
// 插入数据
public void insertGoods () {
    String json = DataUtils.getJson("goods.json", mContext);
    mGoodsModelDao.insertOrReplaceInTx(DataUtils.getGoodsModels(json));
}

5.2.2、查询数据

1)、查询所有
DAO.loadAll();
// 查询所有数据
public List queryGoods () {
    return mGoodsModelDao.loadAll();
}
2)、根据主键查询
DAO.load(Long key);
3)、利用 QueryBuilder 与 properties 设置查询条件
// 查询水果的数据
public List queryFruits () {
    QueryBuilder result = mGoodsModelDao.queryBuilder();
    //借助Property属性类提供的筛选方法
    result = result.where(GoodsModelDao.Properties.Type.eq("0")).orderAsc(GoodsModelDao.Properties.GoodsId);
    return result.list();
}

5.2.3、更新数据

DAO.update(T entity);
DAO.updateInTx(T... entities);
...
// 修改指定商品的商品信息
public void updateGoodsInfo (GoodsModel model) {
    mGoodsModelDao.update(model);
}

5.2.3、删除数据

DAO.delete(T entity);
DAO.deleteAll();
DAO.deleteByKey(K key);
...
// 删除指定商品
public void deleteGoodsInfo (GoodsModel model) {
    mGoodsModelDao.deleteByKey(model.getId());
}

5.2.4、GreenDaoManager 完整代码

public class GreenDaoManager {

    private Context mContext;
    private GoodsModelDao mGoodsModelDao;

    public GreenDaoManager (Context context) {
        this.mContext = context;
        // 获取DAO实例
        mGoodsModelDao = MyApplication.getDaoSession().getGoodsModelDao();
    }

    // 添加所有的数据到数据库
    public void insertGoods () {
        String json = DataUtils.getJson("goods.json", mContext);
        // 如果不想因为重复添加数据而导致崩溃,可以使用insertOrReplaceInTx API
        mGoodsModelDao.insertOrReplaceInTx(DataUtils.getGoodsModels(json));
    }

    // 查询所有的数据
    public List queryGoods () {
        return mGoodsModelDao.loadAll();
    }

    // 查询水果的数据
    public List queryFruits () {
        QueryBuilder result = mGoodsModelDao.queryBuilder();

        //借助Property属性类提供的筛选方法
        result = result.where(GoodsModelDao.Properties.Type.eq("0")).orderAsc(GoodsModelDao.Properties.GoodsId);

        return result.list();
    }

    // 查询零食的数据
    public List querySnacks () {
        QueryBuilder result = mGoodsModelDao.queryBuilder();
        // 借助Property属性类提供的筛选方法
        result = result.where(GoodsModelDao.Properties.Type.eq("1")).orderAsc(GoodsModelDao.Properties.GoodsId);
        return result.list();
    }

    // 修改指定商品的商品信息
    public void updateGoodsInfo (GoodsModel model) {
        mGoodsModelDao.update(model);
    }

    // 删除指定商品
    public void deleteGoodsInfo (GoodsModel model) {
        mGoodsModelDao.deleteByKey(model.getId());
    }

}

六、小结

greenDAO 的使用步骤其实就三步

  1. 创建实体类;
  2. 生成对应的 DaoMasterDaoSessionDao
  3. 通过 Dao 对象完成增删改查

七、案例源码

案例源码已上传至 github,有需要的话可以去下载。

你可能感兴趣的:(android,greendao)