本篇介绍android常用的数据库之一GreenDao的简单用法,增删改查。基于前面搭的框架,当然,你也可以选择不用。看懂用法之后,用起来很方便。GreenDao数据库升级到3.0版本之后api用起来更加方便了,便于让开发人员专注于业务逻辑。我需要额外说明的是,我把之前的项目框架转成了kotlin,不会kotlin语法的同学,可以去研究一下。
添加依赖
最终,我们要添加如下代码,效果图如下:
第一步
打开的你根目录下面的build.gradle文件,也就是项目下面的,并不是app目录下面的build.gradle。
1 | // In your root build.gradle file: |
第二步
打开你的项目下面的build.gradle文件,也就是你的app目录下面的,之前我们添加依赖的时候的那个文件
1 | // In your app projects build.gradle file: |
完成上面两步,辣么,关于greendao的依赖我们就添加完成了
初始化
我们首先得有一个bean类,这个bean类对应的就是数据库表的表结构。我这里想说明的是(敲黑板了),看到了很多网上说的什么主键id必须用Long类型,这种说法是不准确的,准确的说,你的主键字段名称,如果是“id”,辣么,你这个字段“id”,必须用Long类型,如果你换一个名称,比方说“myId”,辣么,你就不必用Long类型,这个问题,说大不大,说小,又困扰了我有一会。我这里新建用户表,就需要一个User的java bean类。如下:
1 | package com.haichenyi.myproject.model.bean; |
这里我把几个常用的注解都写出来了,说一下这几个注解是什么意思
注解 | 意义 |
---|---|
@Entity | 用于标识这是一个需要Greendao帮我们生成代码的bean |
@Id | 标明主键,括号里可以指定是否自增 |
@Property | 用于设置属性在数据库中的列名(默认不写就是保持一致) |
@NotNull | 非空 |
@Transient | 标识这个字段是自定义的不会创建到数据库表里 |
简单的讲一下:
@Entity:标识的bean类,我们在运行的时候,greendao会自动帮我们生成对应的表
@Id:标识的字段就是这个表对应的主键
@Property:标识的字段在表中对应的那一栏的名称是后面括号里面的,这个表height字段对应表中的Height,一般我们直接设置成默认就可以了
@NotNull:标识的字段,这个字段在表中不能为空,不然就出错,所以,在添加数据的时候设置默认值
@Transient:标识的字段,在生成表的时候不会生成对应的字段。这个什么时候用呢?这个,我一般用作标记flag,比方说,从数据库拿数据,又不想重新写一个bean类,就用这个bean类,RecyclerView,填充完数据,item点击的时候,状态发生变化,我们要有一个flag,就通过修改这个字段的值,页面做出相应的变化。
写到这里,我们的bean类也有了,要怎么生成数据库呢?在生成数据库之前,我们先把项目重新clean一遍,再build一遍,看到你刚写的需要生成表的bean类变成了如下样子:
1 | package com.haichenyi.myproject.model.bean; |
如上,greendao通过注解的方式帮我们自动生成了set/get方法,还有构造方法,这就对了,我们不用关,之后我们再执行如下代码生成数据库和表:
1 | DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(getApplicationContext(), "haichenyi.db", null); |
通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。注意:默认的 DaoMaster.DevOpenHelper会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。升级的问题,我们在后面讲,这里我们先把数据库和表先创建了。
上面这个方式是java格式的,由于,我昨天写完框架之后,我把项目转成了kotlin代码,所以这里有点不一样,项目我后面会上传。这里我要说明的是(敲黑板)我用kotlin的时候,碰到了一个问题,当我使用greendao的时候,他提示我,无法引入用注解方式生成的类,dagger2也是一样的,我用java代码写就没有问题,我写这篇博客的时候,目前还没有找到解决的办法。
我用了另外一种方式,采用跟之前网络请求一样的设计模式——装饰者模式。我这里就不多做说明了。我贴出我的代码。
SqlHelper
1 | package com.haichenyi.myproject.model.sql; |
这里定义增删改查4个方法,用于测试这4个功能
SqlImpl
1 | package com.haichenyi.myproject.model.sql; |
功能实现类,看到他的构造方法里面,第二个参数就是我们的数据库名称,后面通过getWritableDb()获取的是可写的数据库,可写就肯定可读。然后就是接口的实现类了,这里就是具体的增删改查功能的实现类,我这里在对应的方法里面就写了Toast,增删改查具体怎么写后面再说
SqlOpenHelper
1 | package com.haichenyi.myproject.model.sql; |
这个类用于管理数据库的表对应的字段发生变化的时候,数据库需要进行的版本更新,连上下面那个类,都是用于版本数据库版本更新的,防止数据丢失。怎么写呢?看到最后面的 UserDao.class 了吗?这个就是我们需要更新的表,你哪个表需要更新,直接写在后面就可以了,这个是可以一次传多个表的,并不是一次只能传一个
MigrationHelper
1 | package com.haichenyi.myproject.model.sql; |
这个类是工具类,拿过去用就好了,还有就是,应用怎么判断是否需要版本更新呢?打开你的app下面的build.grade,在根结点下面添加如下代码:
1 | greendao { |
每当你发布新版本的时候,把这个版本号+1即可。
当然,我门这里依然是用的dagger生成的全局单例,所以,你还需要在你的AppModule下面添加如下代码:
1 | @Provides |
记得把项目重新clean一遍,build一遍,重新跑项目的时候,找到你的数据库。data-data-你的应用包名-databases-haichenyi.db,这个就是我们的数据库。找个Sqlite可视化工具打开,你会看到如下结构。
太多了,不写了,下一篇写增删改查。