博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GreenDao3.0新特性解析(配置、注解、加密)
阅读量:6423 次
发布时间:2019-06-23

本文共 8607 字,大约阅读时间需要 28 分钟。

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常用注解

@Entitypublic 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索引注解

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

其中

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

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

2.4关系注解

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

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

Property property = entity.addLongProperty("customerId").getProperty(); 
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。

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

昵称:

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

  订阅评论

 

[Ctrl+Enter快捷键提交]

 
 
最新IT新闻:
· 
· 
· 
· 
· 
» 
最新知识库文章:
· 
· 
· 
· 
· 
» 
 

转载地址:http://ymrra.baihongyu.com/

你可能感兴趣的文章
6、dnsmasq
查看>>
Java注册登陆学习笔记
查看>>
python学习笔记(一)之列表
查看>>
解析企业Shell面试题
查看>>
CentOS6.0_X86_64 oracle 11g R2 开机自动启动(linux)
查看>>
Android UI开发第二十四篇——Action Bar
查看>>
细说暴库的原理与方法
查看>>
DOS程序SOL中文输出经验
查看>>
限制容器对CPU的使用 - 每天5分钟玩转 Docker 容器技术(28)
查看>>
Docker在CentOS安装文档
查看>>
微软官方下载windows 7啦
查看>>
Windows Phone 实用开发技巧1-20合集(电子书+源代码)
查看>>
获取MDI窗体中控件坐标的方法/屏幕局部截图原位写入
查看>>
Tomcat配置及其LNMT/LAMT/LNAMT实现方式
查看>>
我谈网络扫描 -- 之二
查看>>
Android第三十七期 - 视觉动画下拉刷新
查看>>
Remository3.52简体中文语言包
查看>>
DSL技术分析
查看>>
2015年最新数据库流行排行榜
查看>>
Sql Server 错误5123/5120 附加数据库错误
查看>>