Android使用greenDAO方便SQLite做ORM开发

ORM是指对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。使用它普通的数据库操作不需要去手动编写SQL语句,提高开发效率并减少出错。greenDAO是可以运行在Android平台的一款ORM框架,使用方便,效率也不错,应此很常用。

greenDAO介绍

greenDAOgreenrobot推出的开源产品之一,在GitHub可以获取其源代码。

  • 它的效率很高,超过其他普通的ORM框架
  • 可以支持加密,要求安全存储数据的应用可以加密使存在数据库中的内容不被泄露。
  • 框架的大小不足100kb,所以不会明显增加应用的大小。
  • 不但能存普通数据,还可以存储protobuf,使得适用性很好。

greenDAO官方推荐使用效率更高的新产品ObjectBox,据说效率比Realm还高。不过在普通情况下,greenDAO就可以满足我的需求了。

greenDAO依赖引入

greenDAO需要在编译时做一些额外的操作,所以需要在项目根目录的build.gradle引入额外的插件

1
2
3
4
5
6
7
8
9
10
11
// In your root build.gradle file:
buildscript {
repositories {
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
}
}

在项目需要使用数据库的模块目录下的build.gradle中引入依赖库并执行插件

1
2
3
4
5
6
7
// 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
}

如果需要修改数据库版本,也可以在gradle脚本中指定,当数据表结构改变时,需要升级数据库版本:

1
2
3
4
5
6
7
8
// In the build.gradle file of your app project:
android {
...
}

greendao {
schemaVersion 2
}

这样以后,依赖引入就完成了,接下来就可以进行java代码开发了。

创建数据模型

创建模型就是编写一个普通的实体类,区别在于用一些greenDAO提供的注解来标识类或者成员的特性,例如:一个简单的User实体

1
2
3
4
5
6
7
8
9
10
11
12
@Entity
public class User {
@Id
private Long id;

private String name;

@Transient
private int tempUsageCount; // not persisted

// getters and setters for id and user ...
}

代码中的@Entity就代表这是一个需要用greenDAO持久化的实体。它还可以带更多的参数,用来对这个表做更多的定制:

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
@Entity(
// If you have more than one schema, you can tell greenDAO
// to which schema an entity belongs (pick any string as a name).
schema = "myschema",

// Flag to make an entity "active": Active entities have update,
// delete, and refresh methods.
active = true,

// Specifies the name of the table in the database.
// By default, the name is based on the entities class name.
nameInDb = "AWESOME_USERS",

// Define indexes spanning multiple columns here.
indexes = {
@Index(value = "name DESC", unique = true)
},

// Flag if the DAO should create the database table (default is true).
// Set this to false, if you have multiple entities mapping to one table,
// or the table creation is done outside of greenDAO.
createInDb = false,

// Whether an all properties constructor should be generated.
// A no-args constructor is always required.
generateConstructors = true,

// Whether getters and setters for properties should be generated if missing.
generateGettersSetters = true
)
public class User {
...
}

模型创建完成后,我们只需要编译代码,插件会自动帮我们生成get/set方法,以及带hash的构造方法,当我们修改模型的时候,也要对应修改@Generated注解的方法,或者干脆把他们删了,让插件自动生成。

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
@Entity
public class User {
@Id
private Long id;

private String name;

@Transient
private int tempUsageCount; // not persisted

@Generated(hash = 873297011)
public User(Long id, String name) {
this.id = id;
this.name = name;
}

@Generated(hash = 586692638)
public User() {
}

public Long getId() {
return this.id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}
}

连接数据库

我们的模型创建出来了,就迫不及待的想通过get/set方法来获取和修改数据了,然而操作过数据库的我们都知道,我们还需要一个数据库链接,数据才能做持久化。一般情况下,我们只需要在Application里打开一个数据库链接会话就可以了,之后在业务模块中需要存取数据时复用这个会话就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class App extends Application {
/** A flag to show how easily you can switch from standard SQLite to the encrypted SQLCipher. */
public static final boolean ENCRYPTED = true;

private DaoSession daoSession;

@Override
public void onCreate() {
super.onCreate();

DevOpenHelper helper = new DevOpenHelper(this, ENCRYPTED ? "notes-db-encrypted" : "notes-db");
Database db = ENCRYPTED ? helper.getEncryptedWritableDb("super-secret") : helper.getWritableDb();
daoSession = new DaoMaster(db).newSession();
}

public DaoSession getDaoSession() {
return daoSession;
}
}

如果在业务模块中需要操作数据库时,通过这个全局的session获取某个模型的DAO来做具体的增删改查操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// get the note DAO
DaoSession daoSession = ((App) getApplication()).getDaoSession();
noteDao = daoSession.getNoteDao();

// insert
Note note = new Note();
note.setText(noteText);
note.setComment(comment);
note.setDate(new Date());
note.setType(NoteType.TEXT);
noteDao.insert(note);
Log.d("DaoExample", "Inserted new note, ID: " + note.getId());

// delete
noteDao.deleteByKey(id);

// update
note.setText("This note has changed.");
noteDao.update(note);

如果遇到复杂的业务场景,greenDAO还可以做连接操作,外键,实现一对一,一对多等对应关系。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器