当前位置: 首页 > news >正文

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

Greendao3.0release与7月6日发布,其中最主要的三大改变就是:1.换包名 2.实体注解 3.加密支持的优化

本文里面会遇到一些代码示例,就摘了官方文档和demo里的例子了,因为他们的例子已经写的很好了。

一、GreenDao3的配置

3.0相比2.0的配置较为方便,不用新建Module等一系列操作,可以直接在build.gradle里配置并新建实体用添加注解的方式生成

步骤1/2

build.gradle下添加这些配置(v7包下面的3个是greendao的)

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
    }
}
  
apply plugin: 'org.greenrobot.greendao'
  
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'org.greenrobot:greendao:3.0.1'
    compile 'org.greenrobot:greendao-generator:3.0.0'
    compile 'net.zetetic:android-database-sqlcipher:3.5.2'
}
  
greendao {
    targetGenDir 'src/main/java'
    daoPackage 'com.XXXX.dao.db'
}

步骤2/2

2.2版本是在maingen里使用addEntity,addProperty等方法,3.0只需要手动创建一个实体类加上注解即可(下面会详细说)

build项目,自动生成DaoMaster,Daosession,UserDao等文件,接下来就可以在代码中正常使用了。

二、实体注解

大部分的注解都能找到之前与2.0对应的语法

2.1常用注解

@Entity
public class User {
    @Id(autoincrement = true)
    private Long id;
  
    @Property(nameInDb = "USERNAME")
    private String name;
  
    @NotNull
    private int repos;
  
    @Transient
    private int tempUsageCount;
  
    ...
}

其中

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

@Id 标明主键,括号里可以指定是否自增 相当于2.2版本的

Entity entity = schema.addEntity("User");
entity.addLongProperty("id").primaryKey().autoincrement();

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

@NotNull 非空

@Transient 标识这个字段是自定义的不会创建到数据库表里 相当于2.2版本的

schema.enableKeepSectionsByDefault();

会生成下列代码

// KEEP INCLUDES - put your custom includes here
// KEEP INCLUDES END
   
// KEEP FIELDS - put your custom fields here
// KEEP FIELDS END
   
// KEEP METHODS - put your custom methods here
// KEEP METHODS END

之前想自定义的属性和其getset方法需要写在注释中,现在这个注解就能代替作用

2.2实体类注解

@Entity(
        schema = "myschema",
 
        active = true,
         
        nameInDb = "AWESOME_USERS",
         
        indexes = {
                @Index(value = "name DESC", unique = true)
        },
         
        createInDb = false
)
public class User {
  ...
}

其中

schema是一个项目中有多个schema时 标明要让这个dao属于哪个schema

active 是标明是否支持实体类之间update,refresh,delete等操作 相当于2.2版本的

1
schema.enableActiveEntitiesByDefault();

nameInDb 就是写个存在数据库里的表名(不写默认是一致)

indexes 定义索引,这里可跨越多个列

CreateInDb 如果是有多个实体都关联这个表,可以把多余的实体里面设置为false避免重复创建(默认是true) 

2.3索引注解

@Entity
public class User {
    @Id private Long id;
    @Index(unique = true)
    private String name;
}
 
@Entity
public class User {
    @Id private Long id;
    @Unique private String name;
}

其中

@Index 通过这个字段建立索引

@Unique 添加唯一约束,上面的括号里unique=true作用相同

2.4关系注解

@Entity
public class Order {
    @Id private Long id;
  
    private long customerId;
  
    @ToOne(joinProperty = "customerId")
    private Customer customer;
}
  
@Entity
public class Customer {
    @Id private Long id;

@ToOne 是将自己的一个属性与另一个表建立关联,相当于2.2版本的

Property property = entity.addLongProperty("customerId").getProperty(); <br>entity.addToOne(Customer, property);

@ToMany 的使用场景有些多,下面的代码默认折叠起来

+ View Code

@ToMany的属性referencedJoinProperty,类似于外键约束。

@JoinProperty 对于更复杂的关系,可以使用这个注解标明目标属性的源属性。

@JoinEntity 如果你在做多对多的关系,有其他的表或实体参与,可以给目标属性添加这个额外的注解(感觉不常用吧)

 

2.5派生注解

@Generated 这个是build后greendao自动生成的,这个注解理解为防止重复,每一块代码生成后会加个hash作为标记。 官方不建议你去碰这些代码,改动会导致里面代码与hash值不符。

三、数据库加密

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

compile 'org.greenrobot:greendao-generator-encryption:3.0.0beta3'

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

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。

 

其中

schema是一个项目中有多个schema时 标明要让这个dao属于哪个schema

active 是标明是否支持实体类之间update,refresh,delete等操作 相当于2.2版本的

1
schema.enableActiveEntitiesByDefault();

nameInDb 就是写个存在数据库里的表名(不写默认是一致)

indexes 定义索引,这里可跨越多个列

CreateInDb 如果是有多个实体都关联这个表,可以把多余的实体里面设置为false避免重复创建(默认是true)

 

2.3索引注解

1
2
3
4
5
6
7
8
9
10
11
12
@Entity
public  class  User {
     @Id  private  Long id;
     @Index (unique =  true )
     private  String name;
}
 
@Entity
public  class  User {
     @Id  private  Long id;
     @Unique  private  String name;
}

其中

@Index 通过这个字段建立索引

@Unique 添加唯一约束,上面的括号里unique=true作用相同

 

2.4关系注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Entity
public  class  Order {
     @Id  private  Long id;
  
     private  long  customerId;
  
     @ToOne (joinProperty =  "customerId" )
     private  Customer customer;
}
  
@Entity
public  class  Customer {
     @Id  private  Long id;
}

@ToOne 是将自己的一个属性与另一个表建立关联,相当于2.2版本的

1
Property property = entity.addLongProperty( "customerId" ).getProperty(); <br>entity.addToOne(Customer, property);

@ToMany 的使用场景有些多,下面的代码默认折叠起来

@ToMany的属性referencedJoinProperty,类似于外键约束。

@JoinProperty 对于更复杂的关系,可以使用这个注解标明目标属性的源属性。

@JoinEntity 如果你在做多对多的关系,有其他的表或实体参与,可以给目标属性添加这个额外的注解(感觉不常用吧)

 

2.5派生注解

@Generated 这个是build后greendao自动生成的,这个注解理解为防止重复,每一块代码生成后会加个hash作为标记。 官方不建议你去碰这些代码,改动会导致里面代码与hash值不符。

 

三、数据库加密

在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将其统一,使用更加流畅。

可以直接看写代码使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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出来的,否则只能看到空数据。

1
2
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。

 
分类:  Android相关
标签:  数据库,  Android,  Greendao3.0
好文要顶  关注我  收藏该文   
董铂然
关注 - 17
粉丝 - 494
 
 
+加关注
7
 
 
« 上一篇: Android数据库相关整理
» 下一篇: GreenDao2.2升级GreenDao3.0的适配之路
posted @  2016-07-28 09:09  董铂然 阅读( 16039) 评论( 4)  编辑  收藏
 
 
   回复引用
#1楼   2016-09-02 17:54  zcm3579   
请问greendao3支不支持直接保存基本类型?,还是必须使用Long,Integer这些封装类?
支持(0) 反对(0)
   回复引用
#2楼 [ 楼主2016-09-05 09:23  董铂然   
@ zcm3579
可以使用基本数据类型。
支持(0) 反对(0)
   回复引用
#3楼   2016-09-06 11:44  zcm3579   
@ 董铂然
谢谢,还想请问一般建议使用基本类型还是封装类型? 在旧项目中使用了GreenDao1.X的版本,保存的都是封装类,在使用的时候很多地方都出现了空指针,请问如果GreenDao升级到3.0并且将数据改为基本类型会不会好一点?
支持(0) 反对(0)
   回复引用
#4楼 [ 楼主2016-09-06 15:52  董铂然   
@ zcm3579
建议还是用封装类型吧,因为在传输层本生就都要使用封装类型。如果这个bean就是自己随便用 不走网络,那用普通也行。
支持(0) 反对(0)
 
 
刷新评论 刷新页面 返回顶部
发表评论

昵称:

评论内容:
引用  粗体  链接  缩进  代码  图片
 

 退出 订阅评论

 

[Ctrl+Enter快捷键提交]

 
【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
【力荐】普惠云计算 0门槛体验 30+云产品免费半年
【推荐】可嵌入您系统的“在线Excel”!SpreadJS 纯前端表格控件
【推荐】阿里云“全民云计算”优惠升级
 
美团云0907
最新IT新闻:
·  专家看走眼了 iPhone未来十年还将主导智能手机市场
·  腾讯携手Intel开发区块链技术,推动构建物联网安全能力
·  Linux发行版SUSE诞生二十五周年
·  今日头条停止微博账号服务:二者竞争又加剧
·  全球首款12TB硬盘终于开卖:HGST出品 4530元
»  更多新闻...
极光0908
最新知识库文章:
·  做到这一点,你也可以成为优秀的程序员
·  写给立志做码农的大学生
·  架构腐化之谜
·  学会思考,而不只是编程
·  编写Shell脚本的最佳实践
»  更多知识库文章...
 

相关文章:

  • oracle与mysql的between and
  • 自定义圆角头像图片
  • nbu6.5 for Solaris安装及备份手册
  • 正式英语和非正式英语
  • spring 使用注解注入 list 或 map
  • 使用ADO.NET2.0提升数据交互性能 DataSet 数据表
  • 99%运维人都需要的Linux命令大全
  • 群发邮件功能的完善
  • VHDL——4层电梯系统设计
  • sql注入——避开过滤
  • oracle 截取字符串
  • C# 延时函数
  • MongoDB 学习笔记之 $or与索引关系
  • AS3 角度算法与实现
  • iText pdf 中文问题
  • 【Linux系统编程】快速查找errno错误码信息
  • Leetcode 27 Remove Element
  • October CMS - 快速入门 9 Images And Galleries
  • SSH 免密登录
  • vuex 学习笔记 01
  • Windows Containers 大冒险: 容器网络
  • 爱情 北京女病人
  • 关于使用markdown的方法(引自CSDN教程)
  • 关于字符编码你应该知道的事情
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 深度学习在携程攻略社区的应用
  • 学习笔记:对象,原型和继承(1)
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • #etcd#安装时出错
  • #WEB前端(HTML属性)
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (AngularJS)Angular 控制器之间通信初探
  • (待修改)PyG安装步骤
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (力扣)循环队列的实现与详解(C语言)
  • (算法)Game
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • (转)人的集合论——移山之道
  • .“空心村”成因分析及解决对策122344
  • .jks文件(JAVA KeyStore)
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net程序集学习心得
  • .net中应用SQL缓存(实例使用)
  • /dev/sda2 is mounted; will not make a filesystem here!
  • @ConditionalOnProperty注解使用说明
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • [ccc3.0][数字钥匙] UWB配置和使用(二)
  • [EULAR文摘] 脊柱放射学持续进展是否显著影响关节功能
  • [G-CS-MR.PS02] 機巧之形2: Ruler Circle
  • [Linux] Boot分区满了的处理方法 The volume boot has only 0 bytes disk space remaining
  • [MYSQL]mysql将两个表结果合并到一起