基本使用
导入和配置
- 在项目的build.gradle文件中添加以下代码:
repositories {
google()
jcenter()
mavenCentral() //添加改行
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.android.tools.build:gradle:3.5.3' //添加此行
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' //添加此行
}
- 在模块中的build.gradle中添加:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' //添加此行
dependencies {
implementation 'org.greenrobot:greendao:3.2.2' //添加此行
}
- 在模块中的build.gradle配置参数:
android {
...
}
greendao {
schemaVersion 2 //这个参数用于标识数据库的版本号,用于数据库的升级。
daoPackage "com.example.xxx" //包名
targetGenDir 'build/generated/source/greendao' //自动生成文件的路径(代码中是默认路径)
generateTests true //设为true会在自动生成文件的时候进行测试
targetGenDirTests 'src/androidTest/java' //测试文件的生成路径(同样是默认路径)
}
- 同步gradle。
创建储存数据的实体类
- 编写实体类代码
@Entity( //标志该实体类为greendao的适用范围
nameInDb = "STUDENT", //指定该表的名字,默认从实体类名生成
schema = "mySchema", //如有多个schema,可指定该表归属哪个schema
active = true, //true表明该实体有更新删除刷新的方法,默认false
createInDb = true, //标志该实体是否会在数据库中生成,默认true
generateConstructors = true, //标志是否需要生成全属性的构造方法,默认true
generateGettersSetters = true, //标志是否自动生成getter和setter,默认true
indexes = {
} //定义多列索引(我也没搞懂啥意思)
)
public class Student {
@Id(autoincrement = true)
//标记为id(通常用long类型来作为id),autoincrement为自增长(只有在insert后才有id)
private long id;
@Index(name = "STUDENT_NUM",unique = true) //标志该属性为索引,name是名字,unique是唯一性
private String studentNum;
private String name; //不添加Property的属性默认也会生成列
@Property(nameInDb = "AGE") //标记为属性(一般用于指定列名称)
private int age;
@NotNull //标志该属性不可空
private String sex;
@Transient //标志该属性不需要保存到表中
private String nickName;
}
- 按build菜单的make project按钮并等待构建完成。完成后greendao会自动生成三个java文件:DaoMaster(保存Database对象以及管理session)、DaoSession(可以理解为DAO大管家,管理所有对象的DAO)、StudentDao(具体某个实体类的DAO层,对数据库进行操作)。并会对Student实体类进行一些代码生成(getter,setter,更新删除刷新方法等)。
初始化
在application的oncreate中对数据库进行初始化操作,获得一个全局的session。
public class MyApp extends Application {
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
initGreenDao();//初始化greendao
}
private void initGreenDao() {
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this,"green_db");//使用DaoMaster中的DevOpenHelper来创建数据库。
Database db = helper.getWritableDb();//创建数据库
daoSession = new DaoMaster(db).newSession();//创建该数据库的全局会话
}
public DaoSession getDaoSession() {
return daoSession;//全局会话的getter
}
}
操作数据库
首先对数据库进行操作要先获取对应实体类的会话对象(session)
daoSession = MyApp.getInstance().getDaoSession();//从application中获取全局session
studentDao = daoSession.getStudentDao();
增:
- 构建要储存的对象
String name = String.valueOf(et_name.getText());
String num = String.valueOf(et_num.getText());
String sex = String.valueOf(et_sex.getText());
String age = String.valueOf(et_age.getText());
String nickName = String.valueOf(et_nickname.getText());
Student student = new Student();
student.setAge(age);
student.setName(name);
student.setNickName(nickName);
student.setSex(sex);
student.setStudentNum(num);
- 调用session的insert方法(将对象传入)
studentDao.insert(student);
查:
- 全部查找或按id查找单个对象
List students = studentDao.loadAll();
- 条件查找,greendao提供了queryBuilder这个api来帮助查找,避免了sql语句的复杂性和易错性,当然损失了一定的灵活性。
List students = studentDao.queryBuilder()
.where(StudentDao.Properties.Name.eq(name)) //相当于sql的where语法
.limit(2) //限制最终查找的结果数
.offset(1) //跳过前若干个结果
.list(); //查找与某个名字相同的学生
另外查询的结果不止有list()一种,还有其他三种,以下列举:
- list():将查询结果直接加载到内存(List)中,简单操作,无需关闭。
- listLazy():将查询结果按需加载到内存(LazyList)中,只有访问到才会加载缓存,必须关闭。
- listLazyUncached():每次访问某个实体都将访问数据库,LazyList,必须关闭。
- lazyIterator():使用迭代器来按需遍历对象,不缓存,必须关闭。
后三个懒加载都会在遍历完所有实体后自动关闭,但如果提前结束则需要手动调用close()来关闭。
- 多次查询。在使用了queryBuilder进行查询之后,如果需要再次查询同一个结果,可以再次同该queryBuilder.list()等方法再次获取(这样做更有效率)。或者使用queryBuilder.setParameters()来更改同一个属性的不同参数。
Query query = userDao.queryBuilder().where(
Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970)
).build();//构建一个queryBuilder
List joesOf1970 = query.list();//第一次获取结果
query.setParameter(0, "Maria");//将第0个属性的参数修改为Maria
query.setParameter(1, 1977);//将第1个属性的参数修改为1977
List mariasOf1977 = query.list();//使用同一个queryBuilder进行查询
- 绑定线程查询。如果调用forCurrentThread()来获取当前线程的query。
Query query = studentDao.queryBuilder().build().forCurrentThread();
这样获取的query只能在当前线程进行设置参数和执行这个query,否则会出现异常。但不推荐这样做,在并发事务中操作同一个query对象会导致死锁。并且在调用这个方法时,会将设置为初始参数。
- SQL语句查询。可以使用SQL语句创建query。
删:
- 单个、指定的批量或全部删除。
studentDao.delete(student);//删除单个对象
studentDao.deleteAll();//删除全部
studentDao.deleteByKey(id);//删除该id的对象
studentDao.deleteByKeyInTx(ids);//删除id列表中的所有对象
studentDao.deleteInTx(students);//删除列表中的所有对象
- 利用deleteQuery批量删除符合某些条件的对象。
DeleteQuery query = studentDao.queryBuilder().buildDelete();
query.executeDeleteWithoutDetachingEntities();
改:
studentDao.update(student);
另外还有数据库升级,数据库加密等其他功能容后再整理。