一、GreenDao 简介

  • Android 平台的对象关系映射工具(ORM)
  • 为关系型数据库提供面向对象的接口
  • 简化数据库操作

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

个人觉得Jetpack的Room更好用一些。

1. GreenDao 的核心概念

  • 某实体类 -> 某表
    持久对象,通常实体是使用标准 Java 属性(如 POJO 或 JavaBean)来表示数据库的对象。
    具有一部分 getter/setter 方法的那种类就可以称作 POJO
  • 某DAO -> 数据访问对象(某表的操作)
    数据访问对象(Data Access Object)持续存在并查询实体。对于每个实体,GreenDao 生成一个 Dao,它比 DaoSession 有更多的持久化方法,例如:count、loadAll 和 insertInTx。
  • DaoMaster -> 数据库连接对象
    DaoMaster 保存数据库对象(SQLiteDatabase)并管理特定模式的 Dao 类。它具有静态方法来创建表或将他们删除。其内部类 OpenHelper 和 DevOpenHelper 是在 SQLite 数据库中创建模式的 SQLiteOpenHelper 实现。
  • DaoSession -> 由连接生成的会话
    管理特定模式的所有可用 Dao 对象,您可以使用其中一个 getter 方法获取。DaoSession 还为实体提供了一些通用的持久性方法,如插入、加载、更新、刷新和删除。最后,DaoSession 对象也跟踪一个身份范围。

2. GreenDao 的常用注解

@Entity ——实体注解
@NotNull ——设置表中当前列的值不可为空
@Convert ——指定自定义类型 (@link PropertyConverter)
@Id ——主键Long型,可以通过 @Id(autoincrement = true) 设置自增长
@Index ——创建一 个索引
@JoinEntity ——定义表连接关系
@Unique ——向数据库列添加了一个唯一的约束
@OrderBy ——指定排序

二、GreenDao 使用

1. 导入依赖包

根据官方说明,添加 repository、plugin、library.

Add the following Gradle configuration to your Android project. In your root build.gradle file:

buildscript {
    repositories {
        jcenter()
        mavenCentral() // add repository
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0' // add plugin
    }
}

In your app modules app/build.gradle file:

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
 
dependencies {
    implementation 'org.greenrobot:greendao:3.3.0' // add library
}

2. 会话 Session 创建

创建 MyApplication 类用于存放全局数据。

public class MyApplication extends Application {

    public static DaoSession mSession;

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

    public void initDb () {
        //1.获取需要链接的数据库
        // 获取SQLiteOpenHelper对象devOpenHelper
        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "greendaotest.db");
        // 获取SQLiteDatabase
        SQLiteDatabase db = devOpenHelper.getWritableDatabase();

        //2.创建数据库链接
        DaoMaster daoMaster = new DaoMaster(db);

        //3.创建数据库会话
        // 管理特定模式的所有可用Dao对象
        // DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的Dao类(而不是对象)
        // 它具有静态方法来创建表或将它们删除
        // 其内部类OpenHelper和DevOpenHelper是在SQLite数据库中创建模式的SQLiteOpenHelper实现
        mSession = daoMaster.newSession();
    }
}

AndroidManifest.xml 中指定 MyApplication,设置你所有activity所属于哪个application的。

<application
        android:name=".MyApplication">
</application>

3. 数据库加密

添加依赖包

implementation 'net.zetetic:android-database-sqlcipher:3.5.9@aar'

修改 initDb() 方法

public void initDb () {
    DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "greendaotest2.db");
    //加密数据库
    Database db = devOpenHelper.getEncryptedWritableDb("123");

    DaoMaster daoMaster = new DaoMaster(db);
    mSession = daoMaster.newSession();
}

4. 创建数据库实体 @Entity

创建实体类 GoodsModel.class 并且实现序列化接口 Parcelable

@Entity
public class GoodsModel implements Parcelable {

    @Id(autoincrement = true)
    private Long id;
    private Integer goodsId;
    private String name;
    private String icon;
    private String info;
    private String type;
    
}

根据提示实现方法。

android greenDao 异步 安卓greendao_数据库


android greenDao 异步 安卓greendao_List_02


然后在工具栏中 Make Project.

android greenDao 异步 安卓greendao_List_03


Make Project 之后会自动生成以下文件和代码

android greenDao 异步 安卓greendao_数据_04

android greenDao 异步 安卓greendao_List_05

三、GreenDao 数据处理

首先创建一个实体类 GreenDaoManager.java

public class GreenDaoManager {

    private Context mContext;
    private GoodsModelDao mGoodsModelDao;

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

1. 添加数据

/**
     * 添加所有的数据到数据库
     */
    public void insertGoods() {
        //生成Json数组字符串,将Json数组内的对象添加到List<GoodsModel>中
        String json = DataUtils.getJson("goods.json", mContext);
        List<GoodsModel> goodsModels = DataUtils.getGoodsModels(json);

        //如果不想因为重复添加数据而导致崩溃,可以使用insertOrReplaceInTx API
        //mGoodsModelDao.insertInTx(goodsModels);
        mGoodsModelDao.insertOrReplaceInTx(goodsModels);
    }

insert 的其他方法。

android greenDao 异步 安卓greendao_数据库_06

2. 查询数据

GreenDao 查询数据是创建 QueryBuilder 对象,借助 Property 属性类提供的筛选方法来查询数据。

/**
     * 查询所有数据
     * @return List<GoodsModel>
     */
    public List<GoodsModel> queryGoods() {
        QueryBuilder<GoodsModel> result = mGoodsModelDao.queryBuilder();
        result = result.orderAsc(GoodsModelDao.Properties.GoodsId);
        return result.list();
    }

    /**
     * 查询水果的数据
     * @return List<GoodsModel>
     */
    public List<GoodsModel> queryFruits() {
        //借助Property属性类提供的筛选方法
        QueryBuilder<GoodsModel> result = mGoodsModelDao.queryBuilder()
                .where(GoodsModelDao.Properties.Type.eq("0"))
                .orderAsc(GoodsModelDao.Properties.GoodsId);
        return result.list();
    }

    /**
     * 查询零食的数据
     * @return List<GoodsModel>
     */
    public List<GoodsModel> querySnacks() {
        QueryBuilder<GoodsModel> result = mGoodsModelDao.queryBuilder()
                        .where(GoodsModelDao.Properties.Type.eq("1"))
                        .orderDesc(GoodsModelDao.Properties.GoodsId);
        return result.list();
    }

3. 更新数据

public void updateGoodsInfo(GoodsModel goodsModel) {
        mGoodsModelDao.update(goodsModel);
        mGoodsModelDao.updateInTx();
    }

update 的其他方法。

android greenDao 异步 安卓greendao_数据库_07

4. 删除数据

public void deleteGoodsInfo(GoodsModel goodsModel) {
        mGoodsModelDao.deleteByKey(goodsModel.getId());
    }

delete 的其他方法。

android greenDao 异步 安卓greendao_android greenDao 异步_08

6. 方法使用

参考 MainActivity 中对以上方法对使用。

public class MainActivity extends AppCompatActivity {

    private GreenDaoManager mDBManager;
    private RecyclerView mRv;
    private GoodsAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        configDB();
        configView();
    }

    @Override
    protected void onResume() {
        super.onResume();
        List<GoodsModel> goodsModel = mDBManager.queryGoods();
        mAdapter.setDataSource(goodsModel);
    }

    private void configDB () {
        mDBManager = new GreenDaoManager(this);
    }

    private void configView () {
        mRv = findViewById(R.id.recycler_view);
        mRv.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new GoodsAdapter(this);
        mRv.setAdapter(mAdapter);
    }
    
    public void onAddGoodsClick(View view) {
        mDBManager.insertGoods();
    }

    public void onQueryAllClick(View view) {
        List<GoodsModel> goodsModel = mDBManager.queryGoods();
        mAdapter.setDataSource(goodsModel);
    }

    public void onQueryFruitsClick(View view) {
        mAdapter.setDataSource(mDBManager.queryFruits());
    }

    public void onQuerySnacksClick(View view) {
        mAdapter.setDataSource(mDBManager.querySnacks());
    }
}

案例演示:

使用 RecyclerView 展示数据库的数据。

android greenDao 异步 安卓greendao_数据库_09

附录:

插入的数据来自这里
Assets/goods.json

[
  {
    "goodsId": 2,
    "type": "0",
    "icon": "huolongguo",
    "name": "火龙果",
    "info": "火龙果(学名:Hylocereus undatus 'Foo-Lon')是仙人掌科、量天尺属量天尺的栽培品种,攀援肉质灌木,具气根。"
  },
  {
    "goodsId": 1,
    "type": "1",
    "icon": "chengzi",
    "name": "橙子",
    "info": "橙子(学名:Citrus sinensis 英语:orange),是芸香科柑橘属植物橙树的果实,亦称为黄果、柑子、金环、柳丁。橙子是一种柑果,有很高的食用,药用价值。"
  }
  ...
]

转换 Json 的方法
DataUtils.java

public class DataUtils {

	//读取assets文件夹中的json文件,返回json字符串
    public static String getJson(String fileName, Context context) {
        //将json数据变成字符串
        StringBuilder stringBuilder = new StringBuilder();
        try {
            //获取assets资源管理器
            AssetManager assetManager = context.getAssets();
            //通过管理器打开文件并读取
            BufferedReader bf = new BufferedReader(new InputStreamReader(
                    assetManager.open(fileName)));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }
    
    //将json字符串转换为集合对象
    public static List<GoodsModel> getGoodsModels (String json) {
        final Gson gson = new Gson();
        return gson.fromJson(json, new TypeToken<List<GoodsModel>>() {}.getType());
    }
}

代码下载:https://pan.baidu.com/s/1V2cVntbXusOu2QZSX3LjnQ 密码: dbpb