先看效果图:

添加实体:

按条件查询实体:

GreenDao 概述:
    适用于Android的轻量级快速ORM框架,可将对象映射到SQLite数据库中,并且针对Andriod进行了高度的优化,greenDao提供了出色的性能,并占用了最少的内存。
优点:
    性能上:可能是Android上最快的ORM框架
    易用性上:提供强大并且简洁明了的API
    轻量:最小的内存消耗与小于150kb的库大小

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

greenDao 使用步骤:
1、引入:
    根据github文档引入,具体如下:

将以下Gradle配置添加到你的Android项目中。 在你的根build.gradle文件:

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}
}

在你的app模块app/build.gradle文件:

apply plugin: 'org.greenrobot.greendao' // apply pluginandroid {//greendao配置greendao {// 指定数据库schema版本号,迁移等  c操作会用到schemaVersion 1// 设置生成数据库文件的目录,默认是在build中,可以将生成的文件放到我们的java目录中targetGenDir 'src/main/java'// 设置生成的数据库相关文件的包名,默认为entity所在的包名daoPackage '你的包名.greendao.gen'}
}dependencies {implementation 'org.greenrobot:greendao:3.3.0' // add library
}

2、创建实例类:

@Entity
public class PersonInfo {@Id(autoincrement = true)   //设置自增长private Long id;@Index(unique = true)   //设置唯一性private String perNo;   //人员编号private String name;    //人员姓名private String sex;     //人员性别}

其中@Entity是greenDao的实体注解(用于标识当前实体需要greenDao生成代码)。
    @Id是主键id,Long 类型,可以通过@Id(autoincrement = true)设置自动增长(自动增长主键不能用基本类型long,只能用包装类型Long)。
    @Index(unique = true) 是向数据库添加了唯一约束。

3、自动生成实体类代码:
写完上面实体类代码之后,接下来实体类代码的生成就交给 Android Studio 编译器就可以了,首先我们点击菜单栏中 Build 然后点击 Make Project,等待编译器编译完就可以了,编译完后实体类代码如下所示:

package cnwy.xda.greendaotest.greendao.model;import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Index;
import org.greenrobot.greendao.annotation.Generated;@Entity
public class PersonInfo {@Id(autoincrement = true)   //设置自增长private Long id;@Index(unique = true)   //设置唯一性private String perNo;   //人员编号private String name;    //人员姓名private String sex;     //人员性别@Generated(hash = 428129582)public PersonInfo(Long id, String perNo, String name, String sex) {this.id = id;this.perNo = perNo;this.name = name;this.sex = sex;}@Generated(hash = 1597442618)public PersonInfo() {}public Long getId() {return this.id;}public void setId(Long id) {this.id = id;}public String getPerNo() {return this.perNo;}public void setPerNo(String perNo) {this.perNo = perNo;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public String getSex() {return this.sex;}public void setSex(String sex) {this.sex = sex;}
}

可以选择将这个实体类序列化(不序列化也可以):

package cnwy.xda.greendaotest.greendao.model;import android.os.Parcel;
import android.os.Parcelable;import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Index;
import org.greenrobot.greendao.annotation.Generated;@Entity
public class PersonInfo implements Parcelable {@Id(autoincrement = true)   //设置自增长private Long id;@Index(unique = true)   //设置唯一性private String perNo;   //人员编号private String name;    //人员姓名private String sex;     //人员性别@Generated(hash = 428129582)public PersonInfo(Long id, String perNo, String name, String sex) {this.id = id;this.perNo = perNo;this.name = name;this.sex = sex;}@Generated(hash = 1597442618)public PersonInfo() {}protected PersonInfo(Parcel in) {if (in.readByte() == 0) {id = null;} else {id = in.readLong();}perNo = in.readString();name = in.readString();sex = in.readString();}public static final Creator<PersonInfo> CREATOR = new Creator<PersonInfo>() {@Overridepublic PersonInfo createFromParcel(Parcel in) {return new PersonInfo(in);}@Overridepublic PersonInfo[] newArray(int size) {return new PersonInfo[size];}};public Long getId() {return this.id;}public void setId(Long id) {this.id = id;}public String getPerNo() {return this.perNo;}public void setPerNo(String perNo) {this.perNo = perNo;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public String getSex() {return this.sex;}public void setSex(String sex) {this.sex = sex;}@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {if (id == null) {dest.writeByte((byte) 0);} else {dest.writeByte((byte) 1);dest.writeLong(id);}dest.writeString(perNo);dest.writeString(name);dest.writeString(sex);}
}

(这里实现了 Parcelable 接口是为了在 Activity 之间传递实体类,实现接口的方法一直 Alt + Enter 就可以了)

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

核心类之间的关系:

DaoMaster:

使用 greenDAO 的入口点。DaoMaster 负责管理数据库对象(SQLiteDatabase)和 DAO 类(对象),我们可以通过它内部类 OpenHelper 和 DevOpenHelper SQLiteOpenHelper 创建不同模式的 SQLite 数据库。

DaoSession :

管理指定模式下的所有 DAO 对象,DaoSession提供了一些通用的持久性方法比如插入、负载、更新、更新和删除实体。

XxxDAO :

每个实体类 greenDAO 多会生成一个与之对应DAO对象,如:User 实体,则会生成一个一个UserDao 类

Entities:

可持久化对象。通常, 实体对象代表一个数据库行使用标准 Java 属性(如一个POJO 或 JavaBean )。

4、封装数据库操作类:
因为我们对数据库的操作无非就是增删改查四个操作,所以我们将他们简单封装一下。

package cnwy.xda.greendaotest.greendao.manager;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;import org.greenrobot.greendao.query.Query;import java.util.List;import cnwy.xda.greendaotest.greendao.gen.DaoMaster;
import cnwy.xda.greendaotest.greendao.gen.DaoSession;
import cnwy.xda.greendaotest.greendao.gen.PersonInfoDao;
import cnwy.xda.greendaotest.greendao.model.PersonInfo;public class DbController {/*** Helper*/private DaoMaster.DevOpenHelper mHelper;    //获取Helper对象/*** 数据库*/private SQLiteDatabase db;/*** DaoMaster*/private DaoMaster mDaoMaster;/*** DaoSession*/private DaoSession mDaoSession;/*** 上下文*/private Context mContext;/*** dao*/private PersonInfoDao mPersonInfoDao;private static DbController mDbController;/*** 初始化* @param context*/public DbController(Context context) {this.mContext = context;mHelper = new DaoMaster.DevOpenHelper(context,"person.db",null);mDaoMaster = new DaoMaster(getWritableDatabase());mDaoSession = mDaoMaster.newSession();mPersonInfoDao = mDaoSession.getPersonInfoDao();}/*** 获取可读数据库* @return*/private SQLiteDatabase getReadableDatabase(){if (mHelper == null){mHelper = new DaoMaster.DevOpenHelper(mContext,"person.db",null);}SQLiteDatabase db  = mHelper.getReadableDatabase();return db;}/*** 获取可写数据库* @return*/private SQLiteDatabase getWritableDatabase(){if (mHelper == null){mHelper = new DaoMaster.DevOpenHelper(mContext,"person.db",null);}SQLiteDatabase db = mHelper.getWritableDatabase();return db;}/*** 获取单例*/public static DbController getInstance(Context context){if (mDbController == null){synchronized (DbController.class){if (mDbController==null){mDbController = new DbController(context);}}}return mDbController;}/*** 会自动判定是插入还是替换数据* @param personInfo*/public void insertOrReplace(PersonInfo personInfo){mPersonInfoDao.insertOrReplace(personInfo);}/*** 插入一条记录,表里面要没有与之相同的记录* @param personInfo* @return*/public long insert(PersonInfo personInfo){return mPersonInfoDao.insert(personInfo);}/*** 更新数据* @param personInfo*/public void update(PersonInfo personInfo){PersonInfo mOldPersonInfo = mPersonInfoDao.queryBuilder().where(PersonInfoDao.Properties.Id.eq(personInfo.getId())).build().unique();//拿到之前的记录if (mOldPersonInfo != null){mOldPersonInfo.setName("张伟");mPersonInfoDao.update(mOldPersonInfo);}}/*** 按条件查询数据* @param wherecluse* @return*/public List<PersonInfo> searchByWhere(String wherecluse){Query<PersonInfo> query=mPersonInfoDao.queryBuilder().where(PersonInfoDao.Properties.Name.eq(wherecluse))     /*查询name属性一致的数据*/.orderAsc(PersonInfoDao.Properties.Id).build();return query.list();}/*** 查询所有数据* @return*/public List<PersonInfo> searchAll(){List<PersonInfo> personInfos = mPersonInfoDao.queryBuilder().list();return personInfos;}/*** 删除数据* @param wherecluse*/public void delete(String wherecluse){mPersonInfoDao.queryBuilder().where(PersonInfoDao.Properties.Name.eq(wherecluse))   /*根据name属性查找,然后执行删除*/.buildDelete().executeDeleteWithoutDetachingEntities();}}

5、在activity中使用:

package cnwy.xda.greendaotest;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;import java.util.List;import cnwy.xda.greendaotest.greendao.manager.DbController;
import cnwy.xda.greendaotest.greendao.model.PersonInfo;public class MainActivity extends AppCompatActivity {private Button btnAdd,btnDelete,btnUpdate,btnSearch;private TextView tvDataArea;private EditText etAddPerNo,etAddPerName,etAddPerSex;private EditText etDelete;private EditText etSearch;private DbController mDbController;private PersonInfo personInfo1,personInfo2,personInfo3,personInfo4;private long insertTipId;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mDbController = DbController.getInstance(MainActivity.this);initView();similateData();Envent();}private void similateData() {personInfo1 = new PersonInfo(null,"001","王大宝","男");personInfo2 = new PersonInfo(null,"002","李晓丽","女");personInfo3 = new PersonInfo(null,"003","王大锤","男");personInfo4 = new PersonInfo(null,"004","李玲玲","女");mDbController.insertOrReplace(personInfo1);mDbController.insertOrReplace(personInfo2);mDbController.insertOrReplace(personInfo3);mDbController.insertOrReplace(personInfo4);}private void initView() {btnAdd = findViewById(R.id.btn_add);btnDelete = findViewById(R.id.btn_delete);btnUpdate = findViewById(R.id.btn_update);btnSearch = findViewById(R.id.btn_search);tvDataArea = findViewById(R.id.text_dataArea);etAddPerNo = findViewById(R.id.etAddPerNo);etAddPerName = findViewById(R.id.etAddPerName);etAddPerSex = findViewById(R.id.etAddPerSex);etDelete = findViewById(R.id.et_delete);etSearch = findViewById(R.id.et_search);}private void showDataList(){StringBuilder sb = new StringBuilder();List<PersonInfo>personInfos = mDbController.searchAll();for (PersonInfo personInfo:personInfos){sb.append(" id: ").append(personInfo.getId()).append(" perNo: ").append(personInfo.getPerNo()).append(" name: ").append(personInfo.getName()).append(" sec: ").append(personInfo.getSex()).append("\n");}tvDataArea.setText(sb.toString());}private void Envent(){btnAdd.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String perNo = etAddPerNo.getText().toString().trim();String perName = etAddPerName.getText().toString().trim();String perSex = etAddPerSex.getText().toString().trim();if (perNo.isEmpty()||perName.isEmpty()||perSex.isEmpty()){Toast.makeText(MainActivity.this,"请输入完整的人员信息",Toast.LENGTH_SHORT).show();return;}mDbController.insertOrReplace( new PersonInfo(null,perNo,perName,perSex));showDataList();}});btnDelete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String wherecluse = etDelete.getText().toString().trim();if (wherecluse.isEmpty()){Toast.makeText(MainActivity.this,"请输入删除条件",Toast.LENGTH_SHORT).show();return;}mDbController.delete(wherecluse);showDataList();}});btnUpdate.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mDbController.update(personInfo1);showDataList();}});btnSearch.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String wherecluse = etSearch.getText().toString().trim();StringBuilder sb = new StringBuilder();if (wherecluse.isEmpty()){Toast.makeText(MainActivity.this,"请输入查询条件",Toast.LENGTH_SHORT).show();return;}List<PersonInfo>personInfos = mDbController.searchByWhere(wherecluse);if(personInfos!=null&&personInfos.size()>0){for (PersonInfo personInfo:personInfos){sb.append("id: ").append(personInfo.getId()).append("perNo: ").append(personInfo.getPerNo()).append("name: ").append(personInfo.getName()).append("sec: ").append(personInfo.getSex()).append("\n");}}else{Toast.makeText(MainActivity.this,"该数据为空",Toast.LENGTH_SHORT).show();}tvDataArea.setText(sb.toString());}});}
}

demo源码

官方文档


关于queryBuilde:

参考:Android GreenDao框架使用 进阶篇之queryBuilder

queryBuilder的用法可以通过链式指令来执行,比如

testUserDao.queryBuilder().xx.xx.xx.结束指令。

关于结束指令,如下表:

方法 解释
.list() 查询符合条件的数据
.buildDelete().executeDeleteWithoutDetachingEntities() 删除符合条件的数据
.count() 查询符合条件的个数

关于条件查询,GreenDao提供了很多方法:

方法 解释
where 查询条件(where里的条件必须全部符合)
whereOr 查询条件(where里的条件有符合就可以)
offset 忽略查询出的前n条结果
orderAsc 升序排列
orderDesc 降序排列

下面是条件查询里面的方法:

方法 条件
eq ==
notEq !=
like 模糊查询
between 两个值的区间
in 范围区间
notIn 不在范围区间
gt >
lt <
ge >=
le <=
isNull 为空
isNotNull 不为空

无论是where还是whereOr里面的判断语句都可以是一条或多条,区别在于where里是 “ 且 ” 的关系,而whereOr是 “ 或 ”的关系。

 QueryBuilder<TestUser> qb = testUserDao.queryBuilder();List<TestUser> testUsers = qb.where(qb.and(TestUserDao.Properties.Name.eq(name)
,TestUserDao.Properties.Age.eq(12))).list();
 QueryBuilder<TestUser> qb = testUserDao.queryBuilder();List<TestUser> testUsers = qb.where(TestUserDao.Properties.Name.eq(name)
,qb.or(TestUserDao.Properties.Age.eq(12),TestUserDao.Properties.Age.eq(15))).list();

GreenDao的简单学习(附带demo源码)相关推荐

  1. IoC容器Autofac(2) - 一个简单示例(附demo源码)

    上篇文章中(IoC容器Autofac(1) -- 什么是IoC以及理解为什么要使用Ioc),我们用自己的方式实现了一个简陋的工厂类来实现IoC. 这里我们尝试使用Auotfac来替换我们的工厂类Mov ...

  2. Api demo源码学习(4)--App/Activity/Dialog --Activity以Dialog形式呈现

    这一节实际上比 Api demo源码学习(2)--App/Activity/Custom Dialog 自定义Activity样式  还要简单一些,在源码学习(2)里,也是让Activity以Dial ...

  3. Api demo源码学习(8)--App/Activity/QuickContactsDemo --获取系统联系人信息

    本节通过Content Provider机制获取系统中的联系人信息,注意这个Anctivity直接继承的是ListActivity,所以不再需要setContentView函数来加载布局文件了(我自己 ...

  4. 实现简单的手写板(demo源码)

    在一些软件系统中,需要用到手写涂鸦的功能,然后可以将涂鸦的结果保存为图片,并可以将"真迹"通过网络发送给对方.这种手写涂鸦功能是如何实现的了?最直接的,我们可以使用Windows提 ...

  5. vscode插件开发实践与demo源码

    vscode插件开发实践与demo源码 写在前面 工欲善其事必先利其器.vscode作为优秀的开发工具,给我的日常开发工作提供了极大的便利.其拓展机制更是如此. 但是,最近在做年度专业线任务时,有需要 ...

  6. Android:实际运用Zxing集成二维码扫描 及 自定义扫码界面(demo源码)

    二维码扫描,各大主流App必不可少的功能,而且google已将轮子替我们造好,直接拿来使用即可.以下是教学如何将Zxing开源库集成到自己项目中,并且自定义扫码界面,后期可根据自己的业务需求进行修改, ...

  7. sparkcore分区_Spark学习:Spark源码和调优简介 Spark Core (二)

    本文基于 Spark 2.4.4 版本的源码,试图分析其 Core 模块的部分实现原理,其中如有错误,请指正.为了简化论述,将部分细节放到了源码中作为注释,因此正文中是主要内容. 第一部分内容见: S ...

  8. 深度学习框架Caffe源码解析

    作者:薛云峰(https://github.com/HolidayXue),主要从事视频图像算法的研究, 本文来源微信公众号:深度学习大讲堂.  原文:深度学习框架Caffe源码解析  欢迎技术投稿. ...

  9. winserver的consul部署实践与.net core客户端使用(附demo源码)

    前言 随着微服务兴起,服务的管理显得极其重要.都知道微服务就是"拆",把臃肿的单块应用,拆分成多个轻量级的服务,每个服务可以在短周期内重构.迭代.交付.随着微服务的数量增多,因量变 ...

最新文章

  1. PHP中self和static的区别,php中self与static的区别
  2. 高效开发 Android App 的 10 个建议(转)
  3. 光伏产品发展之路:从反倾销到欧盟加收税款
  4. 编码原则:不变量/前置条件/后置条件
  5. php mysql 随机排序函数_php+mysql实现数据库随机重排实例
  6. 音乐社交APP源码ios版
  7. 《C++ Primer》13.1.1节练习
  8. Seen.js – 使用 SVG 或者 Canvas 渲染 3D 场景
  9. WebSocket教程(一)
  10. 极简风格的响应式简历模板
  11. web.xml中,spring模块化加载xml方式
  12. python快递费用计算_Python制作快递查询系统,来感受到了Python的强大!
  13. [ProblemSolving]ut下载磁盘负荷过重
  14. php大马的使用教程,一php大马,值得研究
  15. Rust中的所有权和借用的关系图
  16. 计算机注册表命令,注册表命令,小编教你电脑怎么打开注册表编辑器
  17. 树莓派数据上传数据库_树莓派内部数据向domoticz的上传
  18. 怎样将文件压缩并传到服务器,客户端上传压缩文件(zip)的思路和实现
  19. 音视频开发-SRS 4.0流媒体服务器系列
  20. 通过usb利用adb实现android手机和pc机通信

热门文章

  1. 内存诊断工程搭建及demo测试
  2. AppleTalk:Apple 公司协议组--网络大典
  3. 钉钉邮箱登录入口_清博舆情钉钉小程序上线 ,五大优势三大亮点助力工作更高效...
  4. 无法打开计算机开始菜单,开始菜单,教您开始菜单无法打开
  5. 过程分析对进行有针对性ICS攻击的意义
  6. Android 接入穿山甲SDK之Banner广告
  7. Java字节码角度分析多态原理 ——提升硬实力8
  8. POJ 图论---1_Uriel's Corner Uriel's Coding Learning Cubing Zone
  9. pytho基础(6)
  10. zoho邮箱收信服务器,配置邮件交付 - Zoho Mail 设置