题记
说点题外话,大概一年半没有用过GreenDao了(甚至于沉溺于JNI海洋的我,连数据库都很少用了),最近换了一份新工作,其中一个老工程引用了GreenDao。由于年事已高,记忆衰退,边查边粘,甚是墨迹,回到家中,整理一二,免得烦恼。废话不说上代码/注释。
一. 插件引入
1. APP级别的gradle
由于我一般会吧Gradle升级成新版本,所以语法形式稍微不一样
1.1 添加plugin
注意老版本的grale是这个酱紫的。。。
apply plugin: 'org.greenrobot.greendao' // apply plugin
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
新版本花里胡哨弄成这样,不过还好,看着算还顺延
plugins {
id 'org.greenrobot.greendao'
id 'com.android.application'
id 'kotlin-android'
}
1.2 dependencies依赖
dependencies {
/*...*/
implementation 'org.greenrobot:greendao:3.3.0'
}
2. project级别的gradle
repositories {
//用下阿里云仓库,稍微快那么一丢丢
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/repository/google' }
google()
jcenter()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0'
}
以上步骤搞完基本上配置就算玩了。
二. Entity实体的新建
我这里偷懒了,是直接用了官网demo改造了一下,把自己想要的数据格式改造下,如果简单功能的话可以直接官网找github工程。
我是选择关了了俩个实体:Note和NoteDetail,代码中有详尽注释,看不懂就是我注释写的不好,我菜(PS:跟我邻桌那个大哥学的)。。。
1. Note.java
我的主表。greendao一般常用的注解我都通过注释一行一行放在代码里了,如果还有没有的NP语法,那就是我用不到并且我不会。
/**
1. 罗列一下GreenDao的注解,并加上注释,便于整理
*/
@Entity(
active = false, // 标记Entity活动状态,活动实体有 update、delete、refresh 方法。默认为 false
nameInDb = "TEST_NOTES",// 表名,默认为类名
createInDb = true,//是否创建表/默认true.多实体对应一个表或者表已创建,不需要 greenDAO 创建时设置 false
generateConstructors = true,// 是否产生所有参数构造器/默认为 true
generateGettersSetters = true//是否生成get/set。默认true
, indexes = {// 定义跨越多列索引
@Index(value = "firstName,lastName DESC", unique = true)
}
)
public class Note {
@Id(autoincrement = true)// 主键只能为 long/ Long 类型,autoincrement自增
private Long id;
@Property(nameInDb = "NAME1") // 列名,默认变量名。默认单词大写,用下划线分割:userName --> USER_NAME
@Index(unique = true, name = "INDEX_NAME1")//为相应的列创建索引
private String firstName;
@Index(unique = true, name = "INDEX_NAME2")
private String lastName;
@NotNull
private String text;
@NotNull//列非空,通常使用标记基本类型(long,int,short,byte),然而可使用包装类型(Long, Integer, Short, Byte)使其可空
private Integer code;
private String comment;
private java.util.Date date;
@Convert(converter = NoteTypeConverter.class, columnType = String.class)
private NoteType type;
/**
* 关联一个实体
*/
private long detailId;//定义外键
@ToOne(joinProperty = "detailId") //一个Note对一个NoteDetail ,joinProperty指定外键
private NoteDetail noteDetail; //持有实体对象
}
2. NoteDetail.java
这个是我待关联的实体,里面只有一个ID。
@Entity
public class NoteDetail {
@Id
private Long id;
}
三. 生成与使用
1. 中间文件的生成与位置。
上面步骤做好之后,点击工程build,就会生成后续需要使用的中间文件,这里最好设置下生成中间的位置,方便自己查看,同时也避免采坑,因为你要是用Kotlin你会发现一些乱七八糟的错误。具体的坑不说了,有兴趣的可以看我另一篇文章。Android中记录那些乱七八糟的报错
配置生成位置
APP级别build.gradle配置如下
plugins {...}
greendao {
schemaVersion 1 //数据库版本
targetGenDir 'src/main/java' //指定生成代码的目录
daoPackage 'com.heima.testgreendao.greenbuild' //生成代码到具体包下
}
android {...}
中间文件
XXDao
:这个是根据你创建的的Entity的名字自动生成的XX 。打开代码看一下,你会发现这里面替你做了一些SQL语句的操作,所以就不用自己拼接字符串了。DaoMaster
与DaoSession
:这是一些对完放开的数据口操作方法,以及配置操作。
因为我建了2个Entity,所以生成文件与位如下。
2. 使用
直接在Application中初始化,可以获取DaoSession对象就好
2.1 Application
初始化
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
instance = this
initGreenDao()
}
/**
* 数据库初始化,一般用于开发
*/
private fun initGreenDao() {
//todo DevOpenHelper 每次数据库升级会清空数据,后续待优化
val helper = DevOpenHelper(this, "notes-db")
val db = helper.writableDb
daoSession = DaoMaster(db).newSession()
}
companion object {
@get:Synchronized
var instance: MyApplication? = null
var daoSession: DaoSession? = null
}
}
2.2 获取对象
// 获取需要操作的Entity的DAO
DaoSession daoSession = MyApplication.Companion.getDaoSession();
noteDao = daoSession.getNoteDao();
2.3 插入
private void addNote() {
String noteText = editText.getText().toString();
editText.setText("");
final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
String comment = "Added on " + df.format(new Date());
Note note = new Note();
// Entity里面设置了@Notnull的属性千万别空着扔进去
note.setText(noteText);
note.setComment(comment);
note.setDate(new Date());
note.setType(NoteType.TEXT);
note.setCode(0);
noteDao.insert(note);
}
2.4 删除
删除方式有很多,大家可以点到API里面去看一下。
官方的demo有个List,我直接获取到实体,得到ID,通过ID删除。
Note note = XXX;
Long noteId = note.getId();
noteDao.deleteByKey(noteId);
2.5 遍历
官方demo中通过某个字段的规则排序,然后顺序遍历了出来。
// 遍历所有实体
Query<Note> notesQuery = noteDao.queryBuilder().orderAsc(NoteDao.Properties.Text).build();
注意Query<Note>
,通过 noteDao实体.queryBuilder().规则操作.build
出来的。下面是源QueryBuilder中的俩种排序方式。
/** Adds the given properties to the ORDER BY section using ascending order. */
public QueryBuilder<T> orderAsc(Property... properties) {
orderAscOrDesc(" ASC", properties);
return this;
}
/** Adds the given properties to the ORDER BY section using descending order. */
public QueryBuilder<T> orderDesc(Property... properties) {
orderAscOrDesc(" DESC", properties);
return this;
}
- orderAsc a-z升序排列
- orderDesc: 降序排序
下面是我根据某个字段的规则的查询。
List<Note> noteList=noteDao.queryBuilder().where(NoteDao.Properties.Text.eq("")).list()
Property字段很重要,他是NoteDao中自动生成的,包括所有单个字段的查询规则。
public static class Properties {
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
public final static Property FirstName = new Property(1, String.class, "firstName", false, "NAME1");
public final static Property LastName = new Property(2, String.class, "lastName", false, "LAST_NAME");
public final static Property Text = new Property(3, String.class, "text", false, "TEXT");
public final static Property Code = new Property(4, Integer.class, "code", false, "CODE");
public final static Property Comment = new Property(5, String.class, "comment", false, "COMMENT");
public final static Property Date = new Property(6, java.util.Date.class, "date", false, "DATE");
public final static Property Type = new Property(7, String.class, "type", false, "TYPE");
public final static Property DetailId = new Property(8, long.class, "detailId", false, "DETAIL_ID");
}
好了,增删改查都熟练了一波。
这个老旧的东西官网已经声明了替代品,抱着第三方库学新不学旧的原则,研究就到此为止了。