一、简介

greenDAO是一个对象关系映射(ORM)的框架,能够提供一个接口通过操作对象的方式去操作关系型数据库,它能够让你操作数据库时更简单、更方便。如下图所示:

android green Android GreenDao_数据库

Github地址:https://github.com/greenrobot/greenDAO

GreenDao 优点:

1.性能高,号称Android最快的关系型数据库
2.内存占用小
3.库文件比较小,小于100K,编译时间低,而且可以避免65K方法限制
4.支持数据库加密 greendao支持SQLCipher进行数据库加密 有关SQLCipher可以参考这篇博客Android数据存储之Sqlite采用SQLCipher数据库加密实战 5.简洁易用的API

二、配置

1、需要在工程(Project)的build.gradle中添加依赖

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.0.0'
        //GreenDao3依赖
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
    }
}

2、在项目(Module)的build.gradle中添加依赖

apply plugin: 'com.android.application'
//使用greendao
apply plugin: 'org.greenrobot.greendao'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.handsome.didi"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    //greendao配置
    greendao {
        //版本号,升级时可配置
        schemaVersion 1                             
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    //greendao依赖
    compile 'org.greenrobot:greendao:3.2.0'
}

三、使用

 

1、创建Bean对象(表名和字段名)

GreenDao需要创建Bean对象之后,该Bean对象就是表名,而它的属性值就是字段名,其实现是通过注释的方式来实现的,下面是购物车的Bean对象(每个Bean对象对应一张表)

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

/**
 * app实体类
 */

@Entity
public class app {
    //不能用int
    @Id(autoincrement = true)
    private Long id;
    private String packageName;
    private String label;
    private String versionName;
    private int versionCode;
    private String sourceDir;
    private String dataDir;
    private boolean system;
    private boolean installed;
    @Generated(hash = 1362904721)
    public app(Long id, String packageName, String label, String versionName,
            int versionCode, String sourceDir, String dataDir, boolean system,
            boolean installed) {
        this.id = id;
        this.packageName = packageName;
        this.label = label;
        this.versionName = versionName;
        this.versionCode = versionCode;
        this.sourceDir = sourceDir;
        this.dataDir = dataDir;
        this.system = system;
        this.installed = installed;
    }
    @Generated(hash = 1515546537)
    public app() {
    }
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getPackageName() {
        return this.packageName;
    }
    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }
    public String getLabel() {
        return this.label;
    }
    public void setLabel(String label) {
        this.label = label;
    }
    public String getVersionName() {
        return this.versionName;
    }
    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }
    public int getVersionCode() {
        return this.versionCode;
    }
    public void setVersionCode(int versionCode) {
        this.versionCode = versionCode;
    }
    public String getSourceDir() {
        return this.sourceDir;
    }
    public void setSourceDir(String sourceDir) {
        this.sourceDir = sourceDir;
    }
    public String getDataDir() {
        return this.dataDir;
    }
    public void setDataDir(String dataDir) {
        this.dataDir = dataDir;
    }
    public boolean getSystem() {
        return this.system;
    }
    public void setSystem(boolean system) {
        this.system = system;
    }
    public boolean getInstalled() {
        return this.installed;
    }
    public void setInstalled(boolean installed) {
        this.installed = installed;
    }
    
}

这里需要注意的是,创建完成之后,需要build gradle来完成我们的代码自动生成。自动生成的代码有

  1. Bean实体的构造方法和get、set方法
  2. DaoMaster、DaoSession、DAOS类

android green Android GreenDao_greenDAO_02

 

这里对Bean对象的注释进行解释

  1. @Entity:告诉GreenDao该对象为实体,只有被@Entity注释的Bean类才能被dao类操作
  2. @Id:对象的Id,使用Long类型作为EntityId,否则会报错。(autoincrement = true)表示主键会自增,如果false就会使用旧值
  3. @Property:可以自定义字段名,注意外键不能使用该属性
  4. @NotNull:属性不能为空
  5. @Transient:使用该注释的属性不会被存入数据库的字段中
  6. @Unique:该属性值必须在数据库中是唯一值
  7. @Generated:编译后自动生成的构造函数、方法等的注释,提示构造函数、方法等不能被修改

2、GreenDao数据库创建

public class MyApplication extends Application {

    private static DaoSession daoSession;

    @Override
    public void onCreate() {
        super.onCreate();
        //配置数据库
        setupDatabase();
    }

    /**
     * 配置数据库
     */
    private void setupDatabase() {
        //创建数据库app.db"
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "app.db", null);
        //获取可写数据库
        SQLiteDatabase db = helper.getWritableDatabase();
        //获取数据库对象
        DaoMaster daoMaster = new DaoMaster(db);
        //获取Dao对象管理者
        daoSession = daoMaster.newSession();
    }

    public static DaoSession getDaoInstant() {
        return daoSession;
    }
}

可以发现,GreenDao已经将我们的数据库创建缩成几句话,代码会自动将Bean对象创建成表,不再是传统的手写SQL语句。这里的数据库创建只需要在Application中执行一次即可,这里对几个类进行解释

  • DevOpenHelper:创建SQLite数据库的SQLiteOpenHelper的具体实现
  • DaoMaster:GreenDao的顶级对象,作为数据库对象、用于创建表和删除表
  • DaoSession:管理所有的Dao对象,Dao对象中存在着增删改查等API

由于我们已经创建好了DaoSession和Shop的Bean对象,编译后会自动生成我们的ShopDao对象,可通过DaoSession获得

AppDao dao = daoSession.getAppDao();

这里的Dao(Data Access Object)是指数据访问接口,即提供了数据库操作一些API接口,可通过dao进行增删改查操作

3、数据库的增删改查

public class utilsDao {

    /**
     * 添加数据,如果有重复则覆盖
     *
     * @param shop
     */
    public static void insertLove(app shop) {
        BaseApplication.getDaoInstant().getShopDao().insertOrReplace(shop);
    }

    /**
     * 删除数据
     *
     * @param id
     */
    public static void deleteLove(long id) {
        BaseApplication.getDaoInstant().getShopDao().deleteByKey(id);
    }

    /**
     * 更新数据
     *
     * @param shop
     */
    public static void updateLove(app shop) {
        BaseApplication.getDaoInstant().getShopDao().update(shop);
    }

    /**
     * 查询条件为Label=秒拍 的数据
     *
     * @return
     */
    public static List<app> queryLove() {
        return BaseApplication.getAppDao().queryBuilder().where(appDao.Properties.Label.eq("秒拍")).list();
    }

    /**
     * 查询全部数据
     */
    public static List<app> queryAll() {
        return BaseApplication.getDaoInstant().getShopDao().loadAll();
    }

}

效果很明显,GreenDao的封装更加短小精悍,语义明朗,下面对GreenDao中Dao对象其他API的介绍

  • 增加单个数据 
  • getShopDao().insert(shop);
  • getShopDao().insertOrReplace(shop);
  • 增加多个数据 
  • getShopDao().insertInTx(shopList);
  • getShopDao().insertOrReplaceInTx(shopList);
  • 查询全部 
  • List< Shop> list = getShopDao().loadAll();
  • List< Shop> list = getShopDao().queryBuilder().list();
  • 查询附加单个条件 
  • .where()
  • .whereOr()
  • 查询附加多个条件 
  • .where(, , ,)
  • .whereOr(, , ,)
  • 查询附加排序 
  • .orderDesc()
  • .orderAsc()
  • 查询限制当页个数 
  • .limit()
  • 查询总个数 
  • .count()
  • 修改单个数据 
  • getShopDao().update(shop);
  • 修改多个数据 
  • getShopDao().updateInTx(shopList);
  • 删除单个数据 
  • getTABUserDao().delete(user);
  • 删除多个数据 
  • getUserDao().deleteInTx(userList);
  • 删除数据ByKey 
  • getTABUserDao().deleteByKey();

 

自己封装的工具类:

import android.content.Context;

import com.example.water.greendao.DaoMaster;
import com.example.water.greendao.DaoSession;

import org.greenrobot.greendao.query.QueryBuilder;

/**
 * Created by Administrator on 2019/8/20
 * <p>
 * desc:
 */
public class DaoManager {
    private static final String DB_NAME = "app.db";//数据库名称
    private static DaoManager mDaoManager;
    private DaoMaster.DevOpenHelper mHelper;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    private Context context;
    public DaoManager(Context context) {
        this.context = context;
    }

    /**
     * 使用单例模式获得操作数据库的对象
     *
     * @return
     */
    public static DaoManager getInstance(Context context) {
        if (mDaoManager == null) {
            synchronized (DaoManager.class) {
                if (mDaoManager == null) {
                    mDaoManager = new DaoManager(context);
                }
            }
        }
        return mDaoManager;
    }

    /**
     * 获取DaoSession
     *
     * @return
     */
    public synchronized DaoSession getDaoSession() {
        if (null == mDaoSession) {
            mDaoSession = getDaoMaster().newSession();
        }
        return mDaoSession;
    }

    /**
     * 设置debug模式开启或关闭,默认关闭
     *
     * @param flag
     */
    public  void setDebug(boolean flag) {
        QueryBuilder.LOG_SQL = flag;
        QueryBuilder.LOG_VALUES = flag;
    }



    /**
     * 关闭数据库
     */
    public synchronized void closeDataBase() {
        closeHelper();
        closeDaoSession();
    }

    /**
     * 判断数据库是否存在,如果不存在则创建
     *
     * @return
     */
    private DaoMaster getDaoMaster() {
        if (null == mDaoMaster) {
            mHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
            mDaoMaster = new DaoMaster(mHelper.getWritableDb());
        }
        return mDaoMaster;
    }

    private void closeDaoSession() {
        if (null != mDaoSession) {
            mDaoSession.clear();
            mDaoSession = null;
        }
    }

    private void closeHelper() {
        if (mHelper != null) {
            mHelper.close();
            mHelper = null;
        }
    }
}

注意:如果增加或者减少基类变量,需要删除变量之外的,按Ctrl+F9 重新生成基类DAO,卸载之前APP,重新运行就不会报错。

(1)orderAsc:升序排序 
(2)orderDesc: 降序排序 
(3)eq():== 
(4)noteq():!= 
(5)gt(): > 
(6)t():< 
(7)ge:>= 
(8)le:<= 
(9)like():包含 
(10)between:俩者之间 
(11)in:在某个值内 
(12)notIn:不在某个值内
userDao.queryBuilder()
  .where(Properties.FirstName.eq("Joe"))
  .orderAsc(Properties.LastName)
  .list();
Query query = daoSession.getNfcDao().queryBuilder()
                .orderDesc(nfcDao.Properties.Nfcnum).build();
        List<nfc> nfcList = query.list();
nfc n = DaoManager.getInstance(HomeActivity.this).getDaoSession().getNfcDao().queryBuilder()
                        .where(nfcDao.Properties.Nfcnum.eq(nfcList.get(i).getNfcnum())).build().unique();
                n.setState(2);
                DaoManager.getInstance(HomeActivity.this).getDaoSession().getNfcDao().update(n);