您的位置:首页 > 数据库

ndroid数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite

2017-01-25 22:28 483 查看


Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite



前不久,我在写了ORMLite这个框架的博文

Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包

但是对于我个人来说,我可能更加倾向于用GreenDao,所以今天也为大家带来了GreenDao的详细博客,希望大家喜欢,之前也详细介绍了ORM的思想,如果不明白可以先看一下前面的博文,这里就不多赘述了,我们新建一个工程




一.相关介绍

官方网站 : http://greendao-orm.com/
Github : https://github.com/greenrobot/greenDAO

传说中的优点

最大性能(最快的 Android ORM)
易于使用API
高度优化
最小内存消耗



那我们可以先来看看怎么集成吧!

集成文档:http://greenrobot.org/greendao/documentation/how-to-get-started/

首先,我们查看Github上的集成步骤,先添加依赖 

我们要添加

compile 'org.greenrobot:greendao:2.2.1'
1
1

同时也要添加Java的项目包

compile 'org.greenrobot:greendao-generator:2.2.0'
1
1

紧接着,我们在main目录下创建一个文件夹java-gen

然后继续在配置文件中添加

//仓库
sourceSets{
main{
java.srcDirs = ['src/main/java','src/main/java-gen']
}
}
1
2
3
4
5
6
1
2
3
4
5
6

最后,新建一个Module,选择Java Library,创建成功后,我们在他的build.gradle下添加

compile 'org.greenrobot:greendao-generator:2.2.0'
1
1


二.实体类

到这里,我们的初步集成算是完成了,是不是比较麻烦,我们看



她说现在去看java-gen有生成代码,实际上我们去看并没有,因为我们需要NoteDao.java,一个数据缓存对象,那我们需要怎么去做呢?我们直接在Module的类里写了

package com.example;

import de.greenrobot.daogenerator.DaoGenerator;
import de.greenrobot.daogenerator.Entity;
import de.greenrobot.daogenerator.Schema;

public class DaoMaker {
public static void main(String[] args) {
//生成数据库的实体类,还有版本号
Schema schema = new Schema(1, "com.student.entity");
addStudent(schema);
//指定dao
schema.setDefaultJavaPackageDao("com.student.dao");
try {
//指定路径
new DaoGenerator().generateAll(schema, "D:\\github\\GreenDao\\app\\src\\main\\java-gen");
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 创建数据库的表
*
* @param schema
*/
public static void addStudent(Schema schema) {
//创建数据库的表
Entity entity = schema.addEntity("Student");
//主键 是int类型
entity.addIdProperty();
//名称
entity.addStringProperty("name");
//年龄
entity.addIntProperty("age");
//地址
entity.addStringProperty("address");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

写完这个时候我们要注意了,我们不能直接去运动这个工程,我们要单独编译这个java类。也就是右键



编译的时间有点点长,我们耐心等待一下就好了,这个时候我们可以看到控制台会打印相关的信息



这个时候你再去看java-gen目录,就会有东西了



很nice,这算是前期基本已经完工了,我们可以看他的原型图




三.核心类

可以看到,GreenDao是有自己创建的类的,我们来看看是什么类

DaoSession:会话层,操作具体dDao类,提供了基本的持久化操作方法,比如对实体对象的insert,load,update,refresh,delete的一些操作

XXDao:实际生成的Dao类,通常对应具体的java类,greenDao为每一个实体类创建一个Dao,他提供了比DaoSession更为具体的付费,比如count,loadALL和inserlnTx,批量插入

xxEntity:持久的实体对象,通常代表数据库row标准的java属性

Schema:实例数据schema,通过schema的版本和缺省的java包调用构造器


四.封装操作类

OK,了解的差不多了,我们就来实战操作一下吧!实战的时候,我们不需要在主Activity中放太多的逻辑代码,全部封装在一个数据库的操作类中其实是最好的,所以我们先新建一个类

package com.lgl.greendao;

import android.content.Context;

import com.student.dao.DaoMaster;
import com.student.dao.DaoSession;

import de.greenrobot.dao.query.QueryBuilder;

/**
* 数据库操作类
* Created by LGL on 2016/7/2.
*/
public class DaoManager {

/**
* 实现功能
* 1.创建数据库
* 2.创建数据库的表
* 3.对数据库的升级
* 4.对数据库的增删查改
*/

//TAG
public static final String TAG = DaoManager.class.getSimpleName();
//数据库名称
private static final String DB_NAME = "greendao.db";
//多线程访问
private volatile static DaoManager manager;
//操作类
private static DaoMaster.DevOpenHelper helper;
//上下文
private Context mContext;
//核心类
private static DaoMaster daoMaster;
private DaoSession daoSession;

//单例模式
public static DaoManager getInstance() {
DaoManager instance = null;
if (manager == null) {
synchronized (DaoManager.class) {
if (instance == null) {
instance = new DaoManager();
manager = instance;
}
}
}
return instance;
}

//传递上下文
public void  initManager(Context context){
this.mContext = context;
}

/**
* 判断是否存在数据库,如果没有则创建
*
* @return
*/
public DaoMaster getDaoMaster() {
if (daoMaster == null) {
helper = new DaoMaster.DevOpenHelper(mContext, DB_NAME, null);
daoMaster = new DaoMaster(helper.getWritableDatabase());
}
return daoMaster;
}

/**
* 完成对数据库的操作,只是个接口
*
* @return
*/
public DaoSession getDaoSession() {
if (daoSession == null) {
if (daoMaster == null) {
daoMaster = getDaoMaster();
}
daoSession = daoMaster.newSession();
}
return daoSession;
}

/**
* 打开输出日志,默认关闭
*/
public void setDebug() {
QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;
}

/**
* 关闭DaoSession
*/
public void closeDaoSession() {
if (daoSession != null) {
daoSession.clear();
daoSession = null;
}
}

/**
* 关闭Helper
*/
public void closeHelper() {
if (helper != null) {
helper.close();
helper = null;
}
}

/**
* 关闭所有的操作
*/
public void closeConnection() {
closeHelper();
closeDaoSession();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

这个类能初始化数据库的很多操作,不过这样还不够,我们需要再写个实在点的操作类,现在只是单单实现一个插入的动作

package com.lgl.greendao;

import android.content.Context;

import com.student.entity.Student;

/**
* 完成对某一张表的具体操作
* Created by LGL on 2016/7/2.
*/
public class CommonUtils {

private DaoManager daoManager;

//构造方法
public CommonUtils(Context context) {
daoManager = DaoManager.getInstance();
daoManager.initManager(context);
}

/**
* 对数据库中student表的插入操作
* @param student
* @return
*/
public boolean insertStudent(Student student) {
boolean flag = false;
flag = daoManager.getDaoSession().insert(student) != -1 ? true : false;
return flag;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32


五.插入

OK,那我们先去看看sql的插入是怎么做的,定义一个button

<Button
android:id="@+id/btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加数据" />
1
2
3
4
5
1
2
3
4
5

我们只需要看他的点击事件就可以了

case R.id.btn_add:
dbUtils = new CommonUtils(this);
Student student = new Student();
student.setName("lgl");
student.setAge(18);
student.setAddress("北京");
dbUtils.insertStudent(student);
break;
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8

我们一运行之后,就可以在data/data/报名/databases中找到数据库了



只要把他到处到桌面上,就可以查看数据了



这里感觉不好,ID应该设置自动增长的对吧!其实只要不设置ID,他就会自增长的


六.批量插入

插入可以了,我们批量插入就简单了,CommonUtils中增加与一个方法

/**
* 批量插入
*
* @param students
* @return
*/
public boolean inserMultStudent(final List<Student> students) {
//标识
boolean flag = false;
try {
//插入操作耗时
daoManager.getDaoSession().runInTx(new Runnable() {
@Override
public void run() {
for (Student student : students) {
daoManager.getDaoSession().insertOrReplace(student);
}
}
});
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

我们可以去验证一下吧,那首先先去写一个button吧

<Button
android:id="@+id/btn_add_mult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="批量添加数据" />
1
2
3
4
5
1
2
3
4
5

这样,我们就可以直接看他的点击事件了

case R.id.btn_add_mult:
List<Student> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Student studentlist = new Student();
studentlist.setName("lgl" + i);
studentlist.setAge(18 + i);
studentlist.setAddress("北京" + i);
list.add(studentlist);
}
dbUtils.inserMultStudent(list);
break;
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11

我们现在把数据库导出来看看



OK,这个非常的nice


七.修改

增删查改嘛,增加说完了,我们来说修改,我们继续写修改的方法然后去验证,这样对于读者来说也是阅读性比较好的

/**
* 修改
* @param student
* @return
*/
public boolean updateStudent(Student student){
boolean flag = false;
try{
daoManager.getDaoSession().update(student);
flag = true;
}catch (Exception e){
e.printStackTrace();
}
return  flag;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

OK,我们去验证一下,写个按钮咯?

<Button
android:id="@+id/btn_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改一条数据" />
1
2
3
4
5
1
2
3
4
5

直接看点击事件

case R.id.btn_update:
Student studentupdate = new Student();
//根据ID来修改
studentupdate.setId((long) 1);
//把年龄改成100岁
studentupdate.setAge(100);
dbUtils.updateStudent(studentupdate);
break;
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8

很好,很强势,我们导出数据库,看看有没有修改成100岁



好,那我们可以看到,虽然被改成了100,但是其他字段为null,因为我们修改的时候没有设置,好吧,设置一下



现在我们可以看到修改了


八.删除

删除就比较简单了,我们直接写

/**
* 删除
*
* @param student
* @return
*/
public boolean deleteStudent(Student student) {
boolean flag = false;
try {
//删除指定ID
daoManager.getDaoSession().delete(student);
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

这样就写个按钮

<Button
android:id="@+id/btn_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除一条数据" />
1
2
3
4
5
1
2
3
4
5

OK,点击事件是比较简单的

case R.id.btn_delete:
Student studentdelete = new Student();
studentdelete.setId((long) 3);
dbUtils.deleteStudent(studentdelete);
break;
1
2
3
4
5
1
2
3
4
5

我们要删除的是他ID为3的数据,那我们运行



可以看到,ID为3的数据已经不见了


九.查询

OK,增删查改我们只剩下查询了,我们先来看一下怎么查询一条语句,写个方法

/**
* 查询单条
*
* @param key
* @return
*/
public Student listOneStudent(long key) {
return daoManager.getDaoSession().load(Student.class, key);
}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9

我们再定义一个button

<Button
android:id="@+id/btn_load"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询一条数据" />
1
2
3
4
5
1
2
3
4
5

这样我们就可以去查询了

case R.id.btn_load:
Log.i(TAG, dbUtils.listOneStudent(5) + "");
break;
1
2
3
1
2
3


十.全部查询

全部查询比较简单

/**
* 全部查询
*
* @return
*/
public List<Student> listAll() {
return daoManager.getDaoSession().loadAll(Student.class);
}
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8

直接去调用就好了

case R.id.btn_load_all:
List<Student> lists = dbUtils.listAll();
Log.i(TAG, lists.toString());
break;
1
2
3
4
1
2
3
4


十一.QueryBuilder

作为最重要的查询,GreenDao肯定是为我们做了很多事情,我们可以翻阅API找到QueryBuilder,这个复合查询该怎么用呢?我们根据条件来进行逻辑查询,原生的有,ORMLite也有,GreenDao也有,我就拿原生的和GreenDao来做对比

/**
* 原生查询
*/
public void queryNative() {
//查询条件
String where = "where name like ? and _id > ?";
//使用sql进行查询
List<Student> list = daoManager.getDaoSession().queryRaw(Student.class, where,
new String[]{"%l%", "6"});
Log.i(TAG, list + "");
}

/**
* QueryBuilder查询大于
*/
public void queryBuilder() {
//查询构建器
QueryBuilder<Student> queryBuilder = daoManager.getDaoSession().queryBuilder(Student.class);
//查询年龄大于19的北京
List<Student> list = queryBuilder.where(StudentDao.Properties.Age.ge(19)).where(StudentDao.Properties.Address.like("北京")).list();
Log.i(TAG, list + "");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

不难看出,使用起来是比较方便的,我们可以无限的加where条件查询


十二.完结

增删查改已经基本上都讲完了,那基本上这个框架也OK了,我们来看一下他运行的截图



逻辑说的还算是比较详细的,但是这个CommonUtils比较零散


CommonUtils

package com.lgl.greendao;

import android.content.Context;
import android.util.Log;

import com.student.dao.StudentDao;
import com.student.entity.Student;

import java.util.List;

import de.greenrobot.dao.query.QueryBuilder;

/**
* 完成对某一张表的具体操作
* Created by LGL on 2016/7/2.
*/
public class CommonUtils {

//TAG
private static final String TAG = CommonUtils.class.getSimpleName();

private DaoManager daoManager;

//构造方法
public CommonUtils(Context context) {
daoManager = DaoManager.getInstance();
daoManager.initManager(context);
}

/**
* 对数据库中student表的插入操作
*
* @param student
* @return
*/
public boolean insertStudent(Student student) {
boolean flag = false;
flag = daoManager.getDaoSession().insert(student) != -1 ? true : false;
return flag;
}

/**
* 批量插入
*
* @param students
* @return
*/
public boolean inserMultStudent(final List<Student> students) {
//标识
boolean flag = false;
try {
//插入操作耗时
daoManager.getDaoSession().runInTx(new Runnable() {
@Override
public void run() {
for (Student student : students) {
daoManager.getDaoSession().insertOrReplace(student);
}
}
});
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}

/**
* 修改
*
* @param student
* @return
*/
public boolean updateStudent(Student student) {
boolean flag = false;
try {
daoManager.getDaoSession().update(student);
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}

/**
* 删除
*
* @param student
* @return
*/
public boolean deleteStudent(Student student) {
boolean flag = false;
try {
//删除指定ID
daoManager.getDaoSession().delete(student);
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
//daoManager.getDaoSession().deleteAll(); //删除所有记录
return flag;
}

/**
* 查询单条
*
* @param key
* @return
*/
public Student listOneStudent(long key) {
return daoManager.getDaoSession().load(Student.class, key);
}

/**
* 全部查询
*
* @return
*/
public List<Student> listAll() {
return daoManager.getDaoSession().loadAll(Student.class);
}

/**
* 原生查询
*/
public void queryNative() {
//查询条件
String where = "where name like ? and _id > ?";
//使用sql进行查询
List<Student> list = daoManager.getDaoSession().queryRaw(Student.class, where,
new String[]{"%l%", "6"});
Log.i(TAG, list + "");
}

/**
* QueryBuilder查询大于
*/
public void queryBuilder() {
//查询构建器
QueryBuilder<Student> queryBuilder = daoManager.getDaoSession().queryBuilder(Student.class);
//查询年龄大于19的北京
List<Student> list = queryBuilder.where(StudentDao.Properties.Age.ge(19)).where(StudentDao.Properties.Address.like("北京")).list();
Log.i(TAG, list + "");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

OK,这个博客算是结束了,我们下一篇再聊


Demo下载:http://download.csdn.net/detail/qq_26787115/9566167

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: