greenDAO 3.0 简介

greenDAO 3.0

greenDAO 是一个对象关系映射(ORM)的框架,能够提供一接口通过操作对象的方式去操作关系型数据库,它能够让你操作数据库是更简单、更方便。

GreenDao

1.greenDAO 优点

  • 性能高
  • 内存占用小
  • 库文件比较小,小于100K,编译时间低,而且可以避免65K方法限制
  • 支持数据库加密,greenDAO 支持 SQLCipher 进行数据库加密
  • 简洁易用的API

greenDAO 3.0 采用注解的方式通过编译方式生成 Java 数据对象和 DAO 对象

2.greenDAO 使用

添加依赖。在 build.gradle添加如下配置
// In your root build.gradle file:
buildscript {
    repositories {
        jcenter()
        mavenCentral() // add repository
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
    }
}

// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin

dependencies {
    compile 'org.greenrobot:greendao:3.2.2' // add library
}

greenDAO 自动生成的 DaoMasterDaoSessionDao,默认位置为 ../app/build/generated/source/greendao/packgename,如果想指定生成DaoMasterDaoSessionDao 的位置,需要在 build.gradle添加如下配置:

greendao {
    schemaVersion 1 //指定数据库schema版本号,迁移等操作会用到
    daoPackage 'com.zhang.greendaodemo.dao' //dao的包名,包名默认是entity所在的包
    targetGenDir 'src/main/java'
}
  • schemaVersion: 数据库schema版本,也可以理解为数据库版本号
  • daoPackage: 设置DaoMaster、DaoSession、Dao包名
  • targetGenDir:设置DaoMaster、DaoSession、Dao目录
  • targetGenDirTest: 设置生成单元测试目录
  • generateTests: 设置自动生成单元测试用例

3.新建实体类

新建如下实体类,点击 Make Project,会自动生成 Setter and Getter并创建对应的DAO文件。

@Entity
public class User {
    @Id(autoincrement = true)
    private Long id;

    @Property(nameInDb = "STUDENTNUM")
    private String studentNum;

    @Property(nameInDb = "NAME")
    @NotNull
    private String name;
}
1.实体类 @Entity 注解
  • schema : 告知greenDAO当前实体属于哪个schema
  • active : 标记一个实体处于活动状态,活动实体有更新、删除和刷新方法
  • nameInDb : 在数据库中使用的别名,默认使用的是实体的类名
  • indexes : 定义索引,可以跨越多个列
  • createInDb : 标记创建数据库表
2.基础属性注解
  • @Id : 主键 Long 型,可以通过 @Id(autoincrement = true) 设置自增长
  • @Property : 设置一个非默认关系映射所对应的列名,默认的是使用字段名。E.g. @Property(nameInDb = "STUDENTNUM")
  • @NotNull : 设置数据库当前列不能为空
  • @Transient : 添加此标记之后不会生成数据库表的列
3.索引注解
  • @Index : 使用 @Index作为一个属性来创建一个索引,通过 name 设置索引别名,也可以通过 unique 给索引添加约束
  • @Unique : 向数据库添加了一个唯一的约束
4.关系注解
  • @ToOne :定义与另一个实体(一个实体对象)的关系,通过joinProperty参数来定义一个外键。
public class Order {    
  @Id 
  private Long id;   

  private long customerId;  

  @ToOne(joinProperty = "customerId")  
  private Customer customer;
}

@Entity
public class Customer {    
    @Id 
    private Long id;
}

Customer 表通过 id 与 Order 表关联,查询 Order 的 Customer 是需要先知道 Order 中的 customerId 然后根据 id = customerId 值在去数据库中查询该id所对应的 Customer 对象。

然而在 greenDAO 中只需要使用 @ToOne注释定义一个关联对象即可。这样只要获得 Order 对象就可以通过 getCustomer()方法回去 Order 所对应的 Customer了。

  • @ToMany : 定义与多个实体对象的关系

    1. referencedJoinProperty 在目标实体中我们需要定义一个与源实体关联起来的外键,即 Order 中的 customerId ,然后需要在源实体里我们需要将 customerId 作为 referencedJoinProperty的属性。
@Entity
  public class Customer {
      @Id private Long id;

      @ToMany(referencedJoinProperty = "customerId")
      @OrderBy("date ASC")
      private List<Order> orders;
  }

  @Entity
  public class Order {
      @Id private Long id;
      private Date date;
      private long customerId;
  }
  1. joinProperties。在 referencedJoinProperty 参数中我们发现两个实体关联的外键是 CustomerId 与 id,但是如果我们的需求是外键不能通过 id 来定义,需要用自己自定义属性来定义,第一种方法就没有用了,而 joinProperties 就是为了解决这个需求的。
@Entity
  public class Customer {
      @Id private Long id;
      @Unique private String tag;

      @ToMany(joinProperties = {
              @JoinProperty(name = "tag", referencedName = "customerTag")
      })
      @OrderBy("date ASC")
      private List<Site> orders;
  }

  @Entity
  public class Order {
      @Id private Long id;
      private Date date;
      @NotNull private String customerTag;
  }

如果改为

@ToMany(joinProperties = {
              @JoinProperty(name = "id", referencedName = "customerId")
      })

这样的话就和第一种方法实现原理是一样的了。

4.创建数据库管理类

public class DBMaster {

    // 是否加密
    public static final boolean ENCRYPTED = false;

    private static String DB_NAME = "student.db";
    private static DaoMaster.DevOpenHelper mHelper;
    private static DaoMaster mDaoMaster;
    private static DaoSession mDaoSession;

    private static volatile DBMaster instance = null;

    private DBMaster() {
        initDatabase();
    }

    public static DBMaster getInstance() {
        if (instance == null) {
            synchronized (DBMaster.class) {
                if (instance == null) {
                    instance = new DBMaster();
                }
            }
        }
        return instance;
    }


    /**
     * 初始化greenDao,这个操作建议在Application初始化的时候添加;
     */
    public static void initDatabase() {
        mHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
        getDaoMaster(context);
        getDaoSession(context);
        mDaoSession = mDaoMaster.newSession();
    }

    /**
     * 获取可读数据库
     */
    public static SQLiteDatabase getReadableDatabase() {
        if (null == mHelper) {
            getInstance();
        }
        return mHelper.getReadableDatabase();
    }

    /**
     * 获取可写数据库
     */
    public static SQLiteDatabase getWritableDatabase() {
        if (null == mHelper) {
            getInstance();
        }
        return mHelper.getWritableDatabase();
    }


    /**
     * 获取DaoMaster
     */
    public static DaoMaster getDaoMaster(Context context) {
        if (null == mDaoMaster) {
            synchronized (DBMaster.class) {
                if (null == mDaoMaster) {
                    MyOpenHelper helper = new MyOpenHelper(context, DB_NAME, null);
                    if (ENCRYPTED) {
                        mDaoMaster = new DaoMaster(helper.getEncryptedWritableDb(DB_NAME)); // 加密数据库
                    } else {
                        mDaoMaster = new DaoMaster(helper.getWritableDatabase());
                    }
                }
            }
        }
        return mDaoMaster;
    }

    /**
     * 获取DaoSession
     */
    public static DaoSession getDaoSession(Context context) {
        if (null == mDaoSession) {
            synchronized (DBMaster.class) {
                mDaoSession = getDaoMaster(context).newSession();
            }
        }
        return mDaoSession;
    }
}

可以在 Application.java中进行数据库初始化工作。

public class MyApplication extends Application{

    public static Context context;

    @Override
    public void onCreate() {
        context = this;
        super.onCreate();
        GreenDaoHelper.initDatabase();
    }
}

5.数据库操作

1.获取 DAO
private StudentMsBeanDao studentMsBeanDao;
studentMsBeanDao = DBMaster.getmDaoSession(getApplicationContext()).getStudentMsBeanDao();
2.插入数据
    /**
     * 插入数据
     */
    private void insert(StudentMsBean studentMsBean) {
        studentMsBeanDao.insert(studentMsBean);
//      studentMsBeanDao.insertOrReplace(studentMsBean); // 插入或新增
//      studentMsBeanDao.save(studentMsBean); // 插入或新增,相较于 insertOrReplace(Object) 可能更有效率,因为如果key已经存在,则不必查询该key是否已经存在
    }

    /**
     * 插入数据集合
     */
    private void insertList(List<StudentMsBean> students){
        if(students == null || students.isEmpty()){
            return;
        }
        studentMsBeanDao.insertInTx(students);
//      studentMsBeanDao.insertOrReplaceInTx(students);
//      studentMsBeanDao.saveInTx(students);
//      studentMsBeanDao.saveInTx(student1,student2,student3);
    }
4.删除数据
        // 删除某一项
        studentMsBeanDao.delete(studentMsBean);
        // 根据主键删除数据
        studentMsBeanDao.deleteByKey((long) 1);
        // 删除全部
        studentMsBeanDao.deleteAll();
        // 删除多个数据
        studentMsBeanDao.deleteInTx(java.lang.Iterable<T> entities);
        // 删除多个数据
        studentMsBeanDao.deleteInTx(studentMsBean1,studentMsBean2,studentMsBean3);
        // 根据 key 删除多个数据
        deleteByKeyInTx(java.lang.Iterable<K> keys);
5.修改数据
        // 修改某项数据
        studentMsBeanDao.update(studentMsBean);
6.查询数据
    private void query() {
        // 查询全部数据
        List<StudentMsBean> list = studentMsBeanDao.loadAll();

        // 查询一条数据
        StudentMsBean studentMsBean = studentMsBeanDao.queryBuilder()
                .where(StudentMsBeanDao.Properties.Name.eq("卫子夫"))
                .build()
                .unique();
    }

运算符

运算符作用
eq=
notEq<>
likeLIKE
betweenBETWEEN … AND …
inIN (…, …, …)
notInNOT IN (…, …, …)
ge>
le<
isNullIS NULL
isNotNullIS NOT NULL

6.数据库加密

greenDAO 支持数据库加密,以保护敏感数据。greenDAO是直接支持 SQLCipher的。SQLCipher是一个自定义使用256位的AES加密的SQLite。

1.添加依赖库
compile 'net.zetetic:android-database-sqlcipher:3.5.1' // 数据库加密依赖库
2.修改 GreenDaoHelper 类
// 获取加密的DaoMaster
mDaoMaster = new DaoMaster(mHelper.getEncryptedWritableDb(DB_NAME);
3.查询加密结果
        // 查询一条数据
        StudentMsBean studentMsBean = studentMsBeanDao.queryBuilder()
                .where(StudentMsBeanDao.Properties.Name.eq("卫子夫"))
                .build()
                .unique();

7.数据库升级

如果我们需要在实体类中增加一个字段或者改变字段属性等,就需要版本更新来保存之前的数据了。

  1. 使用 MigrationHelper
  2. 数据库更新表的方法是 DaoMaster 类中的 onUpgrade 方法,需要构建 MyOpenHelper 帮助类,重写 onUpgrade 方法。

public class MyOpenHelper extends DaoMaster.OpenHelper {
    public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
        super(context, name, factory);
    }

    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        // 操作数据库的更新 有几个表升级都可以传入到下面
        MigrationHelper.getInstance().migrate(db, StudentMsBeanDao.class);
    }
}
  1. 使用 MyOpenHelper 类。需要修改获取 DaoMaster 的方法。使用 MyOpenHelper 代替默认的 DaoMaster.DevOpenHelper来获取 mDaoMaster。
    /**
     * 获取DaoMaster
     */
    public static DaoMaster getDaoMaster(Context context) {
        if (null == mDaoMaster) {
            synchronized (DBMaster.class) {
                if (null == mDaoMaster) {
                    MyOpenHelper helper = new MyOpenHelper(context, DB_NAME, null);
                    if (ENCRYPTED) {
                        mDaoMaster = new DaoMaster(helper.getEncryptedWritableDb(DB_NAME)); // 加密数据库
                    } else {
                        mDaoMaster = new DaoMaster(helper.getWritableDatabase());
                    }
                }
            }
        }
        return mDaoMaster;
    }

4.在 build.gradle 中升级版本

greendao {
    schemaVersion 2 //指定数据库schema版本号,迁移等操作会用到
}

参考

Android数据存储之GreenDao 3.0 详解

深入GreenDao 3.0

greendao3.0以上使用步骤(二):数据库到底该怎么升级

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值