关于GreenDao greenDao是一个将对象映射到SQLite数据库中的轻量且快速的ORM解决方案。关于greenDAO的概念可以看官网greenDAO

greenDAO 优势
1、一个精简的库
2、性能最大化
3、内存开销最小化
4、易于使用的 APIs
5、对 Android 进行高

GreenDao 3.0使用
GreenDao 3.0采用注解的方式来定义实体类,通过gradle插件生成相应的代码。

一,在as中导入相关的包

compile’org.greenrobot:greendao:3.0.1’
compile’org.greenrobot:greendao-generator:3.0.0’

二,在build.gradle中进行配置:

apply plugin: ‘org.greenrobot.greendao’ buildscript {
repositories {
mavenCentral() } dependencies {
classpath ‘org.greenrobot:greendao-gradle-plugin:3.0.0’
} }

  • 在gradle的根模块中加入上述代码。

三,自定义路径

greendao {
schemaVersion 1
daoPackage ‘com.anye.greendao.gen’
targetGenDir ‘src/main/java’ }

  • 在gradle的根模块中加入上述代码,就完成了我们的基本配置了。 属性介绍: schemaVersion–>
    指定数据库schema版本号,迁移等操作会用到; daoPackage –> dao的包名,包名默认是entity所在的包;
    targetGenDir –> 生成数据库文件的目录;

**四,创建一个User的实体

@Entity
public class User {
@Id
private Long id;
private String name;
@Transient private int tempUsageCount;
// not persisted },MakeProject**

  • 编译项目,User实体类会自动编译,生成get、set方法并且会在com.anye.greendao.gen目录下生成三个文件;

greenDao GreenDao使用 public class MyApplication extends Application {
private DaoMaster.DevOpenHelper mHelper; private SQLiteDatabase db;
private DaoMaster mDaoMaster; private DaoSession mDaoSession; public
static MyApplication instances; @Override public void onCreate() {
super.onCreate();
instances = this;
setDatabase(); } public static MyApplication getInstances(){
return instances; }

/* 设置greenDao */ private void setDatabase() {
// 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。
// 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
// 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
// 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
mHelper = new DaoMaster.DevOpenHelper(this, “notes-db”, null);
db = mHelper.getWritableDatabase();
// 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
mDaoMaster = new DaoMaster(db);
mDaoSession = mDaoMaster.newSession(); }
public DaoSession getDaoSession() {
public SQLiteDatabase getDb() {
return db; } }

  • 简单的增删改查实现:

mUser = new User((long)2,”anye3”); mUserDao.insert(mUser);//添加一个

mUserDao.deleteByKey(id);

mUser = new User((long)2,”anye0803”); mUserDao.update(mUser);

List users = mUserDao.loadAll(); String userName = “”; for (int
i = 0; i < users.size(); i++) {
userName += users.get(i).getName()+”,”; }
mContext.setText(“查询全部数据==>”+userNam更多的操作就
不一一介绍了,大家可以根据需要去查找资料;

greendao中的注解
(一) @Entity 定义实体
@nameInDb 在数据库中的名字,如不写则为实体中类名
@indexes 索引
@createInDb 是否创建表,默认为true,false时不创建
@schema 指定架构名称为实体
@active 无论是更新生成都刷新
(二) @Id
(三) @NotNull 不为null
(四) @Unique 唯一约束
(五) @ToMany 一对多
(六) @OrderBy 排序
(七) @ToOne 一对一
(八) @Transient 不存储在数据库中
(九) @generated 由greendao产生的构造函数或方法 快捷键

说明:所有的方法:
***AbstractDao
所有的自动生成的XXDao都是继承于AbstractDao,此类中基本上封装了所有的增删改操作,包括数据库的事务操作。常用的API如下:> void attachEntity(T entity):

long count():获取数据库中数据的数量

// 数据删除相关 void delete(T entity):从数据库中删除给定的实体 void
deleteAll() :删除数据库中全部数据
void deleteByKey(key):从数据库中删除给定Key所对应的实体
void deleteByKeyInTx(java.lang.Iterable keys):使用事务操作删除数据库中给定的所有key所对应的实体
void deleteByKeyInTx(K… keys):使用事务操作删除数据库中给定的所有key所对应的实体
void deleteInTx(java.lang.Iterable entities):使用事务操作删除数据库中给定实体集合中的实体
void deleteInTx(T… entities):使用事务操作删除数据库中给定的实体 // 数据插入相关
long insert(T entity):

将给定的实体插入数据库
void insertInTx(java.lang.Iterable entities):使用事务操作,将给定的实体集合插入数据库
void insertInTx(java.lang.Iterable entities, boolean setPrimaryKey):使用事务操作,将给定的实体集合插入数据库,

设置是否设定主键 void insertInTx(T… entities):将给定的实体插入数据库
long insertOrReplace(T entity):将给定的实体插入数据库,若此实体类存在,则覆盖
void insertOrReplaceInTx(java.lang.Iterableentities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖
void insertOrReplaceInTx(java.lang.Iterable entities, boolean setPrimaryKey):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖

设置是否设定主键
void insertOrReplaceInTx(T…entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖
long insertWithoutSettingPk(T entity):将给定的实体插入数据库,但不设定主键

// 新增数据插入相关API
void save(T entity):将给定的实体插入数据库,若此实体类存在,则更新
void saveInTx(java.lang.Iterableentities):将给定的实体插入数据库,若此实体类存在,则更新
void saveInTx(T… entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则更新

// 加载相关
T load(K key):加载给定主键的实体
java.util.List loadAll():加载数据库中所有的实体
protected java.util.List loadAllAndCloseCursor(android.database.Cursor cursor)
:从cursor中读取、返回实体的列表,并关闭该cursor
protected java.util.List loadAllFromCursor(android.database.Cursor cursor):从cursor中读取、返回实体的列表
T loadByRowId(long rowId) :加载某一行并返回该行的实体
protected T loadUnique(android.database.Cursor cursor) :从cursor中读取、返回唯一实体
protected T loadUniqueAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回唯一实体,并关闭该cursor

//更新数据
void    update(T entity) :更新给定的实体
protected void  updateInsideSynchronized(T entity, DatabaseStatement stmt, boolean lock)
protected void  updateInsideSynchronized(T entity, android.database.sqlite.SQLiteStatement stmt, boolean lock)
void    updateInTx(java.lang.Iterable<T> entities) :使用事务操作,更新给定的实体
void    updateInTx(T... entities):使用事务操作,更新给定的实体  

QueryBuilder、Query

基本查询
GreenDao中,使用QueryBuilder自定义查询实体,而不是再写繁琐的SQL语句,避免了SQL语句的出错率。大家都知道写SQL语句时,非常容易出错,出错后又十分的难查。QueryBuilder真是帮忙解决了一个大麻烦。具体该如何使用呢?

 List joes = userDao.queryBuilder()  // 查询的条件  .where(Properties.FirstName.eq("Joe"))  // 返回实体集合升序排列  .orderAsc(Properties.LastName)  .list();   QueryBuilder qb = userDao.queryBuilder();   // 查询的条件   qb.where(Properties.FirstName.eq("Joe"),   qb.or(Properties.YearOfBirth.gt(1970),   qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));  List youngJoes = qb.list();      
    上面是官方给出的两个列子,不仅满足了查询语句的易写,同时使用了流式写法,提高了代码的可阅读性。 Limit、Offset、Pagination在实际开发过程中,大家肯定碰到这样的问题,当数据过多在一页显示不出来的时候,要么选择前面十条显示,要么分页显示,但是数据总是获取全部的。其实,刚接触GreenDao的时候,也是这么干,获取全部的实体集合,然后再根据实际情况截取。看了API以后,豁然开朗,大神们已经帮我们解决了这件事。此时不得不说,QueryBuilder

中的Limit(限制)、Offset(偏移),limit(int)和offset(int)协同设置,可以完美解决分页显示。 [java]
view plain copy limit(int):限制查询返回结果的数目
offset(int):设置查询结果的偏移量,此查询需与limit(int)结合使用,而不能够脱离limit(int)单独使用
Query
当执行多次查询时,实际是QueryBuilder多次调用Query类。如果执行多次相同的查询,应使用QueryBuilder的build()方法来创建Query,而不是直接使用Query类。如果查询返回的结果是唯一性的,可以使用操作符方法,如果不希望此唯一性不返回
null,此时可调用uniqOrThrow()方法。如果查询返回的结果是多个,可以使返回的结果是一个集合,有如下方法: [java]
view plain copy list():所有实体加载至内存,结果通常是一个ArrayList
listLazy():实体在需要时,加载至内存,表中的第一个元素被第一次访问时会被缓存,下次访问时,使用缓存
listLazyUncached():任何对列表实体的访问懂事从数据库中加载
listIterator():以按需加载的方式来遍历结果,数据没有被缓存
一旦使用QueryBuilder创建了一个query,那么这个Query对象就可以就可以被复用来执行查询显然这种方式逼重新创建一次Query效率要高。
具体来说:

[java] view plain copy 如果Query的参数没有变更,你只需要再次调用List/unuque方法即可
如果参数发生了变化,那么就需要通过setParameter方法来处理每一个发生改变的参数
举例: [java] view plain copy Query query = userDao.queryBuilder().where(Properties.FirstName.eq(“Joe”),
Properties.YearOfBirth.eq(1970)).build(); List joesOf1970 =
query.list();

    现在复用该Query对象:

[java] view plain copy query.setParameter(0, “Maria”);
query.setParameter(1, 1977); List mariasOf1977 = query.list();

    由此可见,Query在执行一次build之后会将查询结果进行缓存,方便下次继续使用。 执行原生SQL语句两种方法:

[java] view plain copy Query query = userDao.queryBuilder().where(
new StringCondition(“_ID IN ” + “(SELECT USER_ID FROM USER_MESSAGE
WHERE READ_FLAG = 0)”).build();
如果这里的QueryBuilder没有提供你想要的特性,可以使用原始的queryRaw或queryRawCreate方法。

[java] view plain copy Query query = userDao.queryRawCreate( “, GROUP
G WHERE G.NAME=? AND T.GROUP_ID=G._ID”, “admin”);
注:写SQL语句时推荐定义常量来表示表名或者表项,这样可以防止出错,因为编译器会检查

六、数据库加密

在Greendao的迭代流程中可以看到这么一个库

1 compile ‘org.greenrobot:greendao-generator-encryption:3.0.0beta3’
Greendao3
与下面这个加密库合作,encryption:3.0.0beta-3相当于一个适配层,之后迭代中并入greendao主库的3.0.1版本,对database相关的api进行了统一。

1 compile ‘net.zetetic:android-database-sqlcipher:3.5.2’
之前的版本也是支持加密的,但是可以理解为在相互api传递数据的时候面临各种类型转换,3.0将其统一,使用更加流畅。

  • 可以直接看写代码使用

User man1 = new User(); man1.setId(10001); man1.setName(“kobe”);
DaoMaster.DevOpenHelper a = new
DaoMaster.DevOpenHelper(this,”database_name”,null); try {
daoSession = new DaoMaster(a.getEncryptedWritableDb(MY_PWD)).newSession();
daoSession.getUserDao().insert(man1); }catch (Exception e){
Log.d(“e”, String.valueOf(e)); }

  • // 若干代码逻辑后。。。

DaoSession normalSession = new
DaoMaster(a.getWritableDb()).newSession();
Log.d(“无法取数据”,normalSession.getUserDao().loadAll().toString());
DaoSession encryptedSession = new
DaoMaster(a.getEncryptedWritableDb(MY_PWD)).newSession();//董铂然 博客园
Log.d(“可以取数据”,encryptedSession.getUserDao().loadAll().toString());

  • 如上方代码所示,相比于之前的方法getWriteableDb,加密的方法是用了getEncryptedWritableDb。
    并在得到DB并getSession时需要输入密钥。 其他的步骤和之前类似。
  • 在取数据时使用的session必须也是使用相同的密钥new出来的,否则只能看到空数据。

07-27 /com.XXX.dsx.testgreendao3 D/无法取数据: [] 07-27
/com.XXX.dsx.testgreendao3 D/可以取数据:
[com.XXX.dsx.testgreendao3.User@2ae5190]

  • 上面的那个MY_PWD是一个静态变量,建议使用本设备的唯一标识类似于UUID的字段做个加密获得,这样每个机器的密钥是不同的,并且不会发生改变。
    • 如果把加密后的数据库的本地文件扒出来,也是查不到内容的, 使用dump仅仅可以看到表结构和列名。

  • 如果觉得还不满意,可以对列名再进行加密。在建表时就对列名加密,后续使用可能会比较麻烦,建议加密一些关键表如USER,ACCOUNT。

七:数据库迁移

  • GreenDaoUpgradeHelper是一个greenDao的数据库升级帮助类。使用它可以很容易解决数据库升级问题,只需一行代码。
  • 原始代码来自stackoverflow。
  • 使用说明
    1.在根目录的build.gradle文件的repositories内添加如下代码:

allprojects { repositories { … maven { url
“https://jitpack.io” } } }

2.添加依赖(greendao 3.0及以上)

dependencies {compile 'org.greenrobot:greendao:3.2.0'compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v2.0.0'
}

如果你使用的greendao是3.0以前的版本,请使用下面的依赖:

dependencies {compile 'de.greenrobot:greendao:2.0.0'compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v1.0.1'
}

3.添加一个新类继承DaoMaster.OpenHelper,添加构造函数并实现onUpgrade方法,在onUpgrade方法添加如下代码即可,参数为所有的Dao类:

MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {

        @Overridepublic void onCreateAllTables(Database db, boolean ifNotExists) {DaoMaster.createAllTables(db, ifNotExists);}@Overridepublic void onDropAllTables(Database db, boolean ifExists) {DaoMaster.dropAllTables(db, ifExists);}},TestDataDao.class, TestData2Dao.class, TestData3Dao.class);

完整代码:

public class MySQLiteOpenHelper extends DaoMaster.OpenHelper {
public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {

                @Overridepublic void onCreateAllTables(Database db, boolean ifNotExists) {DaoMaster.createAllTables(db, ifNotExists);}@Overridepublic void onDropAllTables(Database db, boolean ifExists) {DaoMaster.dropAllTables(db, ifExists);}},TestDataDao.class, TestData2Dao.class, TestData3Dao.class);
}

}

4.初始化

//MigrationHelper.DEBUG = true; //如果你想查看日志信息,请将DEBUG设置为true
MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this, “test.db”,
null);
daoMaster = new DaoMaster(helper.getWritableDatabase());
也可以去链接这篇链接:https://github.com/yuweiguocn/GreenDaoUpgradeHelper/blob/master/README_CH.md

参考文章:
http://blog.csdn.net/njweiyukun/article/details/51893092
http://blog.csdn.net/njweiyukun/article/details/51893092
http://www.jianshu.com/p/793f77feeb89
http://www.cnblogs.com/dsxniubility/archive/2016/07/28/5699543.html
http://blog.csdn.net/io_field/article/details/52214099
http://blog.csdn.net/ddk837239693/article/details/53516298
https://www.daidingkang.cc/2016/12/08/GreenDao/#more

GreenDao3.0 使用(包括导入,具体方法,基本使用,加密,数据库升级等)相关推荐

  1. GreenDao3.0新特性解析(配置、注解、加密)

    Greendao3.0release与7月6日发布,其中最主要的三大改变就是:1.换包名 2.实体注解 3.加密支持的优化 本文里面会遇到一些代码示例,就摘了官方文档和demo里的例子了,因为他们的例 ...

  2. python从包中导入模块_Python中包,模块导入的方法

    Python中包,模块导入的方法 http://www.cnblogs.com/allenblogs/archive/2011/05/24/2055149.html 1. import modname ...

  3. 【ANSYS】ANSYS导入数组方法:MATLAB输出TXT文件导入ANSYS笔记

    个人理解学习笔记,以下部分仅供参考. 1.MATLAB创建数组 clear all rms=1:1000; rms=rms.*0.0000001; x=0:999;x=0.0001.*x';y=zer ...

  4. impdp 并行_EXPDP和IMPDP数据泵进行导出导入的方法

    EXPDP和IMPDP数据泵进行导出导入的方法 使用expdp和impdp时应该注重的事项: 1.exp和imp是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. 2.expdp和impd ...

  5. Python 的 time 模块导入及其方法

    时间模块很重要,Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能,讲解一下Python 的 time 模块导入及其方法. 1,time 模块导入 import time; # ...

  6. 不同版本的SQL Server之间数据导出导入的方法及性能比较

    原文:不同版本的SQL Server之间数据导出导入的方法及性能比较 工作中有段时间常常涉及到不同版本的数据库间导出导入数据的问题,索性整理一下,并简单比较下性能,有所遗漏的方法也欢迎讨论.补充. 0 ...

  7. 刷机提示图像和设备不匹配_安卓5.0升级失败如何解决 安卓5.0刷机失败解决方法介绍【教程】...

    安卓5.0升级失败怎么办?安卓5.0刷机失败急救方法?谷歌发布了适用于Nexus系列的Android 5.0系统,但是,刷安卓5.0系统时遇到system.img系统镜像找不到的错误提示是怎么回事? ...

  8. GreenDao2.2升级GreenDao3.0的适配之路

    前言.为什么要升级到Greendao3.0? 1. 多人开发 以往的数据库建表建Dao等操作要新开一个module,在统一的地方管理数据库建表,现在可以直接写Entity.多人开发时自己管自己的Ent ...

  9. 设计一个长方形类。成员变量包括:长度和宽度,成员函数除包括计算周长和计算面积外, 还包括用set方法来设置长方形的长度和宽度,以及用get的方法来获得长方形的长度和宽度 最后,编写一个测试程序来测试所

    本文为博主原创文章,未经博主允许不得转载. 版权为陈博超所有,第一次于2020年11月22日发表于BLOG上 本BLOG上原创文章未经本人许可,不得用于商业用途.转载请经允许后注明出处,否则保留追究法 ...

最新文章

  1. pandas使用replace函数替换dataframe中的值:replace函数对dataframe中的多个值进行替换、即一次性同时对多个值进行替换操作
  2. 分享一套超棒的iOS “空状态” (empty state) 界面UI设计
  3. POJ 3225 线段树+lazy标记
  4. Asp.Net Core 使用Quartz基于界面画接口管理做定时任务
  5. 图片异步上传,使用ajax上传图片
  6. php如何控制用户对图片的访问 PHP禁止图片盗链
  7. 大型网站技术架构(五)--网站高可用架构(转)
  8. 使用fail2ban防止暴力破解ssh及vsftpd密码
  9. 计算机学win7画图,win7自带画图工具
  10. AA制:用算法解决生活中的AA制问题
  11. java+网络框架netty_GitHub - linyu19872008/getty-1: 一个完全基于java 实现的,长得有点像netty的aio网络框架...
  12. 提供Minimal SD Base Gal/Raf SD基础培养基(含半乳糖/棉子糖)
  13. 人事局计算机应用技术学院,计算机应用技术学校怎么样
  14. 【刷机】nubia z17 root 刷入twrp
  15. 在微信小程序中使用自定义字体【font-family】、同时在canvas
  16. 浙大博士送外卖事件,180度大反转
  17. 如何解决svn is not a working copy
  18. python权限管理设置_python权限管理框架
  19. 短视频营销三大策略玩法,助力实体商家跑通地生活
  20. 1103 缘分数(20分)-- 测试点1、测试4

热门文章

  1. 图解各种数据库数据源(ODBC)配置
  2. ISCSI服务器搭建与配置
  3. 博友的 编写高质量代码 改善java程序的151个建议
  4. 服务器搭建网站:出现503是什么意思?怎么排查?
  5. git版本控制常用指令
  6. 部署kubernetes官网博客
  7. 爱马仕Hermès手表怎么样?
  8. windows批处理脚本bat命令解析【7】EXIT /B 0
  9. Windows10如何去除快捷方式的小箭头
  10. conda创建环境报错conda.core.subdir_data.Response304ContentUnchanged