GreenDao3.0 使用(包括导入,具体方法,基本使用,加密,数据库升级等)

 关于GreenDao greenDao是一个将对象映射到SQLite数据库中的轻量且快速的ORM解决方案。
 关于greenDAO的概念可以看官网greenDAO

greenDAO 优势
1、一个精简的库
2、性能最大化
3、内存开销最小化
4、易于使用的 APIs
5、对 Android 进行高

GreenDao 3.0使用 
GreenDao 3.0采用注解的方式来定义实体类,通过gradle插件生成相应的代码。

一,在as中导入相关的包

compile’org.greenrobot:greendao:3.0.1’
compile’org.greenrobot:greendao-generator:3.0.0’

二,在build.gradle中进行配置:

apply plugin: ‘org.greenrobot.greendao’ buildscript {
repositories {
mavenCentral() } dependencies {
classpath ‘org.greenrobot:greendao-gradle-plugin:3.0.0’
} }

  • 在gradle的根模块中加入上述代码。

三,自定义路径

greendao {
schemaVersion 1
daoPackage ‘com.anye.greendao.gen’
targetGenDir ‘src/main/java’ }

  • 在gradle的根模块中加入上述代码,就完成了我们的基本配置了。 属性介绍: schemaVersion–>
    指定数据库schema版本号,迁移等操作会用到; daoPackage –> dao的包名,包名默认是entity所在的包;
    targetGenDir –> 生成数据库文件的目录;

**四,创建一个User的实体

@Entity
public class User {
@Id
private Long id;
private String name;
@Transient private int tempUsageCount;
// not persisted },MakeProject**

  • 编译项目,User实体类会自动编译,生成get、set方法并且会在com.anye.greendao.gen目录下生成三个文件;

greenDao GreenDao使用 public class MyApplication extends Application {
private DaoMaster.DevOpenHelper mHelper; private SQLiteDatabase db;
private DaoMaster mDaoMaster; private DaoSession mDaoSession; public
static MyApplication instances; @Override public void onCreate() {
super.onCreate();
instances = this;
setDatabase(); } public static MyApplication getInstances(){
return instances; }

/* 设置greenDao */ private void setDatabase() {
// 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。
// 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
// 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
// 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
mHelper = new DaoMaster.DevOpenHelper(this, “notes-db”, null);
db = mHelper.getWritableDatabase();
// 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
mDaoMaster = new DaoMaster(db);
mDaoSession = mDaoMaster.newSession(); }
public DaoSession getDaoSession() {
public SQLiteDatabase getDb() {
return db; } }

  • 简单的增删改查实现:

mUser = new User((long)2,”anye3”); mUserDao.insert(mUser);//添加一个

mUserDao.deleteByKey(id);

mUser = new User((long)2,”anye0803”); mUserDao.update(mUser);

List users = mUserDao.loadAll(); String userName = “”; for (int
i = 0; i < users.size(); i++) {
userName += users.get(i).getName()+”,”; }
mContext.setText(“查询全部数据==>”+userNam更多的操作就
不一一介绍了,大家可以根据需要去查找资料;

greendao中的注解
(一) @Entity 定义实体
@nameInDb 在数据库中的名字,如不写则为实体中类名
@indexes 索引
@createInDb 是否创建表,默认为true,false时不创建
@schema 指定架构名称为实体
@active 无论是更新生成都刷新
(二) @Id
(三) @NotNull 不为null
(四) @Unique 唯一约束
(五) @ToMany 一对多
(六) @OrderBy 排序
(七) @ToOne 一对一
(八) @Transient 不存储在数据库中
(九) @generated 由greendao产生的构造函数或方法 快捷键

说明:所有的方法:
***AbstractDao
所有的自动生成的XXDao都是继承于AbstractDao,此类中基本上封装了所有的增删改操作,包括数据库的事务操作。常用的API如下:> void attachEntity(T entity):

long count():获取数据库中数据的数量

// 数据删除相关 void delete(T entity):从数据库中删除给定的实体 void
deleteAll() :删除数据库中全部数据
void deleteByKey(key):从数据库中删除给定Key所对应的实体
void deleteByKeyInTx(java.lang.Iterable keys):使用事务操作删除数据库中给定的所有key所对应的实体
void deleteByKeyInTx(K… keys):使用事务操作删除数据库中给定的所有key所对应的实体
void deleteInTx(java.lang.Iterable entities):使用事务操作删除数据库中给定实体集合中的实体
void deleteInTx(T… entities):使用事务操作删除数据库中给定的实体 // 数据插入相关
long insert(T entity):

将给定的实体插入数据库
void insertInTx(java.lang.Iterable entities):使用事务操作,将给定的实体集合插入数据库
void insertInTx(java.lang.Iterable entities, boolean setPrimaryKey):使用事务操作,将给定的实体集合插入数据库,

设置是否设定主键 void insertInTx(T… entities):将给定的实体插入数据库
long insertOrReplace(T entity):将给定的实体插入数据库,若此实体类存在,则覆盖
void insertOrReplaceInTx(java.lang.Iterableentities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖
void insertOrReplaceInTx(java.lang.Iterable entities, boolean setPrimaryKey):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖

设置是否设定主键
void insertOrReplaceInTx(T…entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖
long insertWithoutSettingPk(T entity):将给定的实体插入数据库,但不设定主键

// 新增数据插入相关API
void save(T entity):将给定的实体插入数据库,若此实体类存在,则更新
void saveInTx(java.lang.Iterableentities):将给定的实体插入数据库,若此实体类存在,则更新
void saveInTx(T… entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则更新

// 加载相关
T load(K key):加载给定主键的实体
java.util.List loadAll():加载数据库中所有的实体
protected java.util.List loadAllAndCloseCursor(android.database.Cursor cursor)
:从cursor中读取、返回实体的列表,并关闭该cursor
protected java.util.List loadAllFromCursor(android.database.Cursor cursor):从cursor中读取、返回实体的列表
T loadByRowId(long rowId) :加载某一行并返回该行的实体
protected T loadUnique(android.database.Cursor cursor) :从cursor中读取、返回唯一实体
protected T loadUniqueAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回唯一实体,并关闭该cursor

//更新数据  
void    update(T entity) :更新给定的实体  
protected void  updateInsideSynchronized(T entity, DatabaseStatement stmt, boolean lock)   
protected void  updateInsideSynchronized(T entity, android.database.sqlite.SQLiteStatement stmt, boolean lock)   
void    updateInTx(java.lang.Iterable entities) :使用事务操作,更新给定的实体  
void    updateInTx(T... entities):使用事务操作,更新给定的实体  

QueryBuilder、Query

基本查询
GreenDao中,使用QueryBuilder自定义查询实体,而不是再写繁琐的SQL语句,避免了SQL语句的出错率。大家都知道写SQL语句时,非常容易出错,出错后又十分的难查。QueryBuilder真是帮忙解决了一个大麻烦。具体该如何使用呢?

 List joes = userDao.queryBuilder()  
                   // 查询的条件  
                   .where(Properties.FirstName.eq("Joe"))  
                   // 返回实体集合升序排列  
                   .orderAsc(Properties.LastName)  
                   .list();   QueryBuilder qb = userDao.queryBuilder();   // 查询的条件   qb.where(Properties.FirstName.eq("Joe"),   qb.or(Properties.YearOfBirth.gt(1970),   qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));  
                    List youngJoes = qb.list();      
    上面是官方给出的两个列子,不仅满足了查询语句的易写,同时使用了流式写法,提高了代码的可阅读性。 Limit、Offset、Pagination
    在实际开发过程中,大家肯定碰到这样的问题,当数据过多在一页显示不出来的时候,要么选择前面十条显示,要么分页显示,但是数据总是获取全部的。其实,刚接触GreenDao的时候,也是这么干,获取全部的实体集合,然后再根据实际情况截取。看了API以后,豁然开朗,大神们已经帮我们解决了这件事。此时不得不说,QueryBuilder

中的Limit(限制)、Offset(偏移),limit(int)和offset(int)协同设置,可以完美解决分页显示。 [java]
view plain copy limit(int):限制查询返回结果的数目
offset(int):设置查询结果的偏移量,此查询需与limit(int)结合使用,而不能够脱离limit(int)单独使用
Query
当执行多次查询时,实际是QueryBuilder多次调用Query类。如果执行多次相同的查询,应使用QueryBuilder的build()方法来创建Query,而不是直接使用Query类。如果查询返回的结果是唯一性的,可以使用操作符方法,如果不希望此唯一性不返回
null,此时可调用uniqOrThrow()方法。如果查询返回的结果是多个,可以使返回的结果是一个集合,有如下方法: [java]
view plain copy list():所有实体加载至内存,结果通常是一个ArrayList
listLazy():实体在需要时,加载至内存,表中的第一个元素被第一次访问时会被缓存,下次访问时,使用缓存
listLazyUncached():任何对列表实体的访问懂事从数据库中加载
listIterator():以按需加载的方式来遍历结果,数据没有被缓存
一旦使用QueryBuilder创建了一个query,那么这个Query对象就可以就可以被复用来执行查询显然这种方式逼重新创建一次Query效率要高。
具体来说:

[java] view plain copy 如果Query的参数没有变更,你只需要再次调用List/unuque方法即可
如果参数发生了变化,那么就需要通过setParameter方法来处理每一个发生改变的参数
举例: [java] view plain copy Query query = userDao.queryBuilder().where(Properties.FirstName.eq(“Joe”),
Properties.YearOfBirth.eq(1970)).build(); List joesOf1970 =
query.list();

    现在复用该Query对象:

[java] view plain copy query.setParameter(0, “Maria”);
query.setParameter(1, 1977); List mariasOf1977 = query.list();

    由此可见,Query在执行一次build之后会将查询结果进行缓存,方便下次继续使用。 执行原生SQL语句

两种方法:

[java] view plain copy Query query = userDao.queryBuilder().where(
new StringCondition(“_ID IN ” + “(SELECT USER_ID FROM USER_MESSAGE
WHERE READ_FLAG = 0)”).build();
如果这里的QueryBuilder没有提供你想要的特性,可以使用原始的queryRaw或queryRawCreate方法。

[java] view plain copy Query query = userDao.queryRawCreate( “, GROUP
G WHERE G.NAME=? AND T.GROUP_ID=G._ID”, “admin”);
注:写SQL语句时推荐定义常量来表示表名或者表项,这样可以防止出错,因为编译器会检查

六、数据库加密

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

  • 可以直接看写代码使用

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。

七:数据库迁移

  • GreenDaoUpgradeHelper是一个greenDao的数据库升级帮助类。使用它可以很容易解决数据库升级问题,只需一行代码。
  • 原始代码来自stackoverflow。
  • 使用说明
    1.在根目录的build.gradle文件的repositories内添加如下代码:

allprojects { repositories { … maven { url
“https://jitpack.io” } } }

2.添加依赖(greendao 3.0及以上)

dependencies {
        compile 'org.greenrobot:greendao:3.2.0'
        compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v2.0.0'
}

如果你使用的greendao是3.0以前的版本,请使用下面的依赖:

dependencies {
        compile 'de.greenrobot:greendao:2.0.0'
        compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v1.0.1'
}

3.添加一个新类继承DaoMaster.OpenHelper,添加构造函数并实现onUpgrade方法,在onUpgrade方法添加如下代码即可,参数为所有的Dao类:

MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {

        @Override
        public void onCreateAllTables(Database db, boolean ifNotExists) {
            DaoMaster.createAllTables(db, ifNotExists);
        }

        @Override
        public void onDropAllTables(Database db, boolean ifExists) {
            DaoMaster.dropAllTables(db, ifExists);
        }
    },TestDataDao.class, TestData2Dao.class, TestData3Dao.class);

完整代码:

public class MySQLiteOpenHelper extends DaoMaster.OpenHelper {
public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {

                @Override
                public void onCreateAllTables(Database db, boolean ifNotExists) {
                    DaoMaster.createAllTables(db, ifNotExists);
                }

                @Override
                public void onDropAllTables(Database db, boolean ifExists) {
                    DaoMaster.dropAllTables(db, ifExists);
                }
            },TestDataDao.class, TestData2Dao.class, TestData3Dao.class);
}

}

4.初始化

//MigrationHelper.DEBUG = true; //如果你想查看日志信息,请将DEBUG设置为true
MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this, “test.db”,
null);
daoMaster = new DaoMaster(helper.getWritableDatabase());
也可以去链接这篇链接:https://github.com/yuweiguocn/GreenDaoUpgradeHelper/blob/master/README_CH.md

参考文章:
http://blog.csdn.net/njweiyukun/article/details/51893092
http://blog.csdn.net/njweiyukun/article/details/51893092
http://www.jianshu.com/p/793f77feeb89
http://www.cnblogs.com/dsxniubility/archive/2016/07/28/5699543.html
http://blog.csdn.net/io_field/article/details/52214099
http://blog.csdn.net/ddk837239693/article/details/53516298
https://www.daidingkang.cc/2016/12/08/GreenDao/#more

你可能感兴趣的:(Android,日常记录)