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。
谢谢,还想请问一般建议使用基本类型还是封装类型? 在旧项目中使用了GreenDao1.X的版本,保存的都是封装类,在使用的时候很多地方都出现了空指针,请问如果GreenDao升级到3.0并且将数据改为基本类型会不会好一点?
建议还是用封装类型吧,因为在传输层本生就都要使用封装类型。如果这个bean就是自己随便用 不走网络,那用普通也行。
【力荐】普惠云计算 0门槛体验 30+云产品免费半年
【推荐】可嵌入您系统的“在线Excel”!SpreadJS 纯前端表格控件
【推荐】阿里云“全民云计算”优惠升级
· 专家看走眼了 iPhone未来十年还将主导智能手机市场
· 腾讯携手Intel开发区块链技术,推动构建物联网安全能力
· Linux发行版SUSE诞生二十五周年
· 今日头条停止微博账号服务:二者竞争又加剧
· 全球首款12TB硬盘终于开卖:HGST出品 4530元
» 更多新闻...
· 写给立志做码农的大学生
· 架构腐化之谜
· 学会思考,而不只是编程
· 编写Shell脚本的最佳实践
公告
#本博客内所有随笔均为原创!#
#欢迎前往我的github查看各种开源项目#
联系邮箱:
dantesx2012@gmail.com
GitHub地址:
https://github.com/dsxNiubility
园龄: 2年7个月
粉丝: 494
关注: 17
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
27 | 28 | 29 | 30 | 31 | 1 | 2 | |||
3 | 4 | 5 | 6 | 7 | 8 | 9 | |||
10 | 11 | 12 | 13 | 14 | 15 | 16 | |||
17 | 18 | 19 | 20 | 21 | 22 | 23 | |||
24 | 25 | 26 | 27 | 28 | 29 | 30 | |||
1 | 2 | 3 | 4 | 5 | 6 | 7 |