Android 数据库--greenDAO 3.0 的基本使用方法

安卓开发主要使用的存储方式有三种:

文件存储
数据库存储
网络存储

一般轻量级存储,我们使用文件存储就够用了,但是一旦涉及大量存储数据时候,文件存储就显得很笨重了,这个时候就需要我们使用数据库存储了,android系统是自带 SQLite轻量级嵌入式数据库引擎,并提供了相应的调用api,但是书写复杂,大多数开发者都会选择封装后再使用,或者挑选一个开源库来使用。目前主流的的数据库有:

LitePal 郭霖大神出品的一款开源的orm数据库

afinal 是一个android的sqlite orm 和 ioc 框架。同时封装了android中的http框架,使其更加简单易用。FinalDB模块,android中的orm框架,一行代码就可以进行增删改查。支持一对多,多对一等查询。

ORMLite(Object Relational Mapping Lite)提供了一些轻量级持久化Java对象到SQL数据库,同时也避免了复杂性和更多的标准的ORM包的开销功能。它支持的SQL数据库使用JDBC的数量,还支持原生的Android操作系统数据库API调用sqlite

SugarORM 是对象关系映射模式。不用写复杂的sql语句,而用简单的API即可完成创建和操纵数据;可以在原有的Bean上仅仅添加小的修改而复用Bean;简化而明了的数据库设计和创建过程,同时提供表的一对多的支持。

Realm 是用来替代sqlite的一种解决方案,它有一套自己的数据库存储引擎,比sqlite更轻量级,拥有更快的速度,并且具有很多现代数据库的特性,比如支持JSON,流式api,数据变更通知,自动数据同步,简单身份验证,访问控制,事件处理,最重要的是跨平台,目前已有Java,Objective C,Swift,React-Native,Xamarin这五种实现。

LiteOrm 和 DBFlow等

本文主要讲解greenDAO 3.0 GreenDao是为Android设计的对象关系映射(ORM)工具。它提供了对象到关系型数据库SQLite的相应接口。为了在Android工程中使用greenDao,需要创建另一个“生成器”工程,它的任务是在你的工程域里生成具体的代码。因此相比与其它ORM框架具有出众性能。

基本用法

第一步,在根目录(最外层)下的 build.gradle内添加 greenDao 插件

// In your root build.gradle file:
buildscript {
    repositories {
        jcenter()
        mavenCentral() // add repository
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.1'  //这个是当前用的 gradle 版本
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
    }
}

第二步,在工程目录下的 build.gradle 内添加相关依赖

// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
 
dependencies {
    implementation 'org.greenrobot:greendao:3.2.2' // add library  compile 在新版gradle里已经不建议使用了
}

第三步 指定greenDao 自动生成代码的目录,在工程目录下的 build.gradle 添加如下

greendao {
    schemaVersion 1 //指定数据库schema版本号,迁移等操作会用到
    daoPackage 'xxx.xx.xxx.greendao'//通过gradle插件生成的数据库相关文件  xxx.xxx.xx 一般填写包名
    targetGenDir 'src/main/java'  //自定义生成数据库文件的目录
}

第三步 编写自己所需要的实体类 对实体类加一些注解 此处以我写的代码分析一哈

@Entity //这个注解必须要 告诉greenDao这是一个实体类
public class TokenEntity implements Serializable {
    static final long serialVersionUID = -15515456L;
    @Id  //标识为id  可选 还有大量注解 可查询官方文档
    private String id;
    private String address;
    private String name;
    private String tag;
    private String tokenAddress;
    private double balance;

一些常用注解
@Entity 用于标识这是一个需要Greendao帮我们生成代码的bean

@Id 标明主键,括号里可以指定是否自增

@Property 用于设置属性在数据库中的列名(默认不写就是保持一致)

@NotNull 非空

@Transient 标识这个字段是自定义的不会创建到数据库表里

@Unique 添加唯一约束

第四步,自动生成代码,点击make project greenDAO插件 会帮我们生成一些文件。


Android 数据库--greenDAO 3.0 的基本使用方法_第1张图片
image.png

首先实体类的变化,构造方法和set,get方法都自动生成

@Entity
public class TokenEntity implements Serializable {
    static final long serialVersionUID = -15515456L;
    @Id
    private String id;
    private String address;
    private String name;
    private String tag;
    private String tokenAddress;
    private double balance;
    private long decimals; //精度
    @Generated(hash = 194050609)
    public TokenEntity(String id, String address, String name, String tag,
            String tokenAddress, double balance, long decimals) {
        this.id = id;
        this.address = address;
        this.name = name;
        this.tag = tag;
        this.tokenAddress = tokenAddress;
        this.balance = balance;
        this.decimals = decimals;
    }
....

项目里src下也会新增相关类,DaoMaster,DaoSession和实体类的Dao


Android 数据库--greenDAO 3.0 的基本使用方法_第2张图片
image.png

不封装基本使用,非常不建议

//DB_NAME 自己定义的数据库名字
 DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(RuntimeContext.getApplication(),DB_NAME,null); 
        mDaoMaster = new DaoMaster(devOpenHelper.getWritableDb());
        mDaoSession = mDaoMaster.newSession();
        mDaoSession.getTokenEntityDao().insert(new TokenEntity()); //获取实体类的entityDao api 提供增删改查

简单封装
DBManager.class 单例模式 获取数据库的 master 和session

/**
 * 数据库管理类
 */
public class DBManager {
    final static String DB_NAME = "xxx_db";
    private static DBManager mInstance;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    private DBManager(){
        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(RuntimeContext.getApplication(),DB_NAME,null);
        mDaoMaster = new DaoMaster(devOpenHelper.getWritableDb());
        mDaoSession = mDaoMaster.newSession();
    }

    public DaoMaster getDaoMaster() {
        return mDaoMaster;
    }

    public DaoSession getDaoSession() {
        return mDaoSession;
    }
    public static DBManager getInstance(){
        if(mInstance==null){
            synchronized (DBManager.class){
                if(mInstance==null){
                    mInstance = new DBManager();
                }
            }
        }
        return mInstance;
    }
}

针对每个实体类编写工具类,后期替换别的数据库,或者改动会方便很多,此处以我写的token实体编写增删改查工具类,本来想通过反射写一个通用的增删改成类,结果发现查的时候每个表的属性都不一样就放弃。

/**
 * 负责token 表的增删改查
 */
public class TokenDbUtil {
    public static boolean insert(TokenEntity entity){
        try {
            DBManager.getInstance().getDaoSession().getTokenEntityDao().insert(entity);
        }catch (Exception e){
            return false;
        }
        return true;
    }
    public static boolean insertOrReplace(TokenEntity entity){
        try {
            DBManager.getInstance().getDaoSession().getTokenEntityDao().insertOrReplace(entity);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    /**
     * 批量插入
     * @param list
     * @return
     */
    public static boolean insertBatch(List list){
        try {
            DBManager.getInstance().getDaoSession().getTokenEntityDao().insertInTx(list);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    public static boolean update(TokenEntity entity){
        try {
            DBManager.getInstance().getDaoSession().getTokenEntityDao().update(entity);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    /**
     * 通过地址查询 该address下拥有的token
     * @param address
     * @return
     */
    public static List queryByAddress(String address){
        List list = null;
        list =DBManager.getInstance().getDaoSession().getTokenEntityDao()
                .queryBuilder()
                .where(TokenEntityDao.Properties.Address.eq(address)).build().list();
        return list;
    }

    public static boolean delete(TokenEntity entity){
        try {
            DBManager.getInstance().getDaoSession().getTokenEntityDao().delete(entity);
        }catch (Exception e){
            return false;
        }
        return true;
    }
}

greenDAO 基本使用方法就写到这里了。

greenDAO 开发中遇到的一些小坑

1.开发中突然想加一些实体类属性,发现在跑App时报各种错,删掉App重新装,因为新增属性,会改变表结构,而又没有更新build.gradle 里版本号, 数据库就会出错。
2.实体类序列化,一开始没想到该实体类需要序列化,再加上 implements Serializable 代码时候出各种错,删掉代码里的@Generated(hash = xxxxx) 重新 make project

  1. 各种打印java.lang.ClassNotFoundException: Didn’t find class “net.sqlcipher.database.SQLiteOpenHelper
    的log , 虽然不影响使用,但是还是很烦,因为greenDAO 用到加密相关的东西,而这个库没有被加入,在build.gradle 里加入
implementation 'net.zetetic:android-database-sqlcipher:3.4.0@aar'

就不报这个异常了。这里又有一个坑,官方文档给的 https://www.zetetic.net/sqlcipher/sqlcipher-for-android/
版本可能不存在,当初按官网文档走,怎么都下载不下来。由于多加了一个库,App体积也变大了不少,如果没有用到加密库,那就不用加这个库了。看到这里了,点个赞呗。

你可能感兴趣的:(Android 数据库--greenDAO 3.0 的基本使用方法)