zoukankan      html  css  js  c++  java
  • 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版本的

    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(); 
    entity.addToOne(Customer, property);

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

    @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。

  • 相关阅读:
    HIVE源码(5):HQL 转换为 MR 源码详细解读(4)
    HIVE源码(4):HQL 转换为 MR 源码详细解读(3)HQL 生成 AST(抽象语法树)
    HIVE源码(3):HQL 转换为 MR 源码详细解读(2)
    HIVE源码(2):HQL 转换为 MR 源码详细解读(1)
    HIVE源码(1):HQL 是如何转换为 MR 任务的
    FLINK基础(103): DS算子与窗口(14)多流转换算子(5) Interval Join
    FLINK基础(93): DS算子与窗口(7)单流算子(6) 窗口算子 Window/WindowAll/Window Apply/WindowReduce
    FLINK基础(92): DS算子与窗口(6)单流算子(5)KeyBy(1)
    FLINK基础(85):DS状态机制(11) 总结
    1822. Sign of the Product of an Array
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/9288492.html
Copyright © 2011-2022 走看看