配色: 字号:
Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite
2016-10-10 | 阅:  转:  |  分享 
  
Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite


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


传说中的优点
最大性能(最快的AndroidORM)
易于使用API
高度优化
最小内存消耗

首先,我们查看Github上的集成步骤,先添加依赖
我们要添加
compile''org.greenrobot:greendao:2.2.1''

同时也要添加Java的项目包
compile''org.greenrobot:greendao-generator:2.2.0''

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

然后继续在配置文件中添加
//仓库
sourceSets{
main{
java.srcDirs=[''src/main/java'',''src/main/java-gen'']
}
}

最后,新建一个Module,选择JavaLibrary,创建成功后,我们在他的build.gradle下添加
compile''org.greenrobot:greendao-generator:2.2.0''

二.实体类

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

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

importde.greenrobot.daogenerator.DaoGenerator;
importde.greenrobot.daogenerator.Entity;
importde.greenrobot.daogenerator.Schema;

publicclassDaoMaker{
publicstaticvoidmain(String[]args){
//生成数据库的实体类,还有版本号
Schemaschema=newSchema(1,"com.student.entity");
addStudent(schema);
//指定dao
schema.setDefaultJavaPackageDao("com.student.dao");
try{
//指定路径
newDaoGenerator().generateAll(schema,"D:\\github\\GreenDao\\app\\src\\main\\java-gen");
}catch(Exceptione){
e.printStackTrace();
}
}

/
创建数据库的表

@paramschema
/
publicstaticvoidaddStudent(Schemaschema){
//创建数据库的表
Entityentity=schema.addEntity("Student");
//主键是int类型
entity.addIdProperty();
//名称
entity.addStringProperty("name");
//年龄
entity.addIntProperty("age");
//地址
entity.addStringProperty("address");
}
}

写完这个时候我们要注意了,我们不能直接去运动这个工程,我们要单独编译这个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中放太多的逻辑代码,全部封装在一个数据库的操作类中其实是最好的,所以我们先新建一个类
packagecom.lgl.greendao;

importandroid.content.Context;

importcom.student.dao.DaoMaster;
importcom.student.dao.DaoSession;

importde.greenrobot.dao.query.QueryBuilder;

/
数据库操作类
CreatedbyLGLon2016/7/2.
/
publicclassDaoManager{


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

//TAG
publicstaticfinalStringTAG=DaoManager.class.getSimpleName();
//数据库名称
privatestaticfinalStringDB_NAME="greendao.db";
//多线程访问
privatevolatilestaticDaoManagermanager;
//操作类
privatestaticDaoMaster.DevOpenHelperhelper;
//上下文
privateContextmContext;
//核心类
privatestaticDaoMasterdaoMaster;
privateDaoSessiondaoSession;

//单例模式
publicstaticDaoManagergetInstance(){
DaoManagerinstance=null;
if(manager==null){
synchronized(DaoManager.class){
if(instance==null){
instance=newDaoManager();
manager=instance;
}
}
}
returninstance;
}

//传递上下文
publicvoidinitManager(Contextcontext){
this.mContext=context;
}

/
判断是否存在数据库,如果没有则创建

@return
/
publicDaoMastergetDaoMaster(){
if(daoMaster==null){
helper=newDaoMaster.DevOpenHelper(mContext,DB_NAME,null);
daoMaster=newDaoMaster(helper.getWritableDatabase());
}
returndaoMaster;
}

/
完成对数据库的操作,只是个接口

@return
/
publicDaoSessiongetDaoSession(){
if(daoSession==null){
if(daoMaster==null){
daoMaster=getDaoMaster();
}
daoSession=daoMaster.newSession();
}
returndaoSession;
}

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

/
关闭DaoSession
/
publicvoidcloseDaoSession(){
if(daoSession!=null){
daoSession.clear();
daoSession=null;
}
}

/
关闭Helper
/
publicvoidcloseHelper(){
if(helper!=null){
helper.close();
helper=null;
}
}

/
关闭所有的操作
/
publicvoidcloseConnection(){
closeHelper();
closeDaoSession();
}




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

importandroid.content.Context;

importcom.student.entity.Student;

/
完成对某一张表的具体操作
CreatedbyLGLon2016/7/2.
/
publicclassCommonUtils{

privateDaoManagerdaoManager;

//构造方法
publicCommonUtils(Contextcontext){
daoManager=DaoManager.getInstance();
daoManager.initManager(context);
}

/
对数据库中student表的插入操作
@paramstudent
@return
/
publicbooleaninsertStudent(Studentstudent){
booleanflag=false;
flag=daoManager.getDaoSession().insert(student)!=-1?true:false;
returnflag;
}
}

五.插入

OK,那我们先去看看sql的插入是怎么做的,定义一个button
android:id="@+id/btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加数据"/>

我们只需要看他的点击事件就可以了
caseR.id.btn_add:
dbUtils=newCommonUtils(this);
Studentstudent=newStudent();
student.setName("lgl");
student.setAge(18);
student.setAddress("北京");
dbUtils.insertStudent(student);
break;

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

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

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

@paramstudents
@return
/
publicbooleaninserMultStudent(finalListstudents){
//标识
booleanflag=false;
try{
//插入操作耗时
daoManager.getDaoSession().runInTx(newRunnable(){
@Override
publicvoidrun(){
for(Studentstudent:students){
daoManager.getDaoSession().insertOrReplace(student);
}
}
});
flag=true;
}catch(Exceptione){
e.printStackTrace();
}
returnflag;
}

我们可以去验证一下吧,那首先先去写一个button吧
android:id="@+id/btn_add_mult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="批量添加数据"/>

这样,我们就可以直接看他的点击事件了
caseR.id.btn_add_mult:
Listlist=newArrayList<>();
for(inti=0;i<10;i++){
Studentstudentlist=newStudent();
studentlist.setName("lgl"+i);
studentlist.setAge(18+i);
studentlist.setAddress("北京"+i);
list.add(studentlist);
}
dbUtils.inserMultStudent(list);
break;

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

OK,这个非常的nice
七.修改

增删查改嘛,增加说完了,我们来说修改,我们继续写修改的方法然后去验证,这样对于读者来说也是阅读性比较好的
/
修改
@paramstudent
@return
/
publicbooleanupdateStudent(Studentstudent){
booleanflag=false;
try{
daoManager.getDaoSession().update(student);
flag=true;
}catch(Exceptione){
e.printStackTrace();
}
returnflag;
}

OK,我们去验证一下,写个按钮咯?
android:id="@+id/btn_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改一条数据"/>

直接看点击事件
caseR.id.btn_update:
Studentstudentupdate=newStudent();
//根据ID来修改
studentupdate.setId((long)1);
//把年龄改成100岁
studentupdate.setAge(100);
dbUtils.updateStudent(studentupdate);
break;

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

现在我们可以看到修改了
八.删除

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

@paramstudent
@return
/
publicbooleandeleteStudent(Studentstudent){
booleanflag=false;
try{
//删除指定ID
daoManager.getDaoSession().delete(student);
flag=true;
}catch(Exceptione){
e.printStackTrace();
}
returnflag;
}

这样就写个按钮
android:id="@+id/btn_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除一条数据"/>

OK,点击事件是比较简单的
caseR.id.btn_delete:
Studentstudentdelete=newStudent();
studentdelete.swww.shanxiwang.netetId((long)3);
dbUtils.deleteStudent(studentdelete);
break;

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

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

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

@paramkey
@return
/
publicStudentlistOneStudent(longkey){
returndaoManager.getDaoSession().load(Student.class,key);
}

我们再定义一个button
android:id="@+id/btn_load"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询一条数据"/>

这样我们就可以去查询了
caseR.id.btn_load:
Log.i(TAG,dbUtils.listOneStudent(5)+"");
break;

十.全部查询

全部查询比较简单
/
全部查询

@return
/
publicListlistAll(){
returndaoManager.getDaoSession().loadAll(Student.class);
}

直接去调用就好了
caseR.id.btn_load_all:
Listlists=dbUtils.listAll();
Log.i(TAG,lists.toString());
break;

十一.QueryBuilder

作为最重要的查询,GreenDao肯定是为我们做了很多事情,我们可以翻阅API找到QueryBuilder,这个复合查询该怎么用呢?我们根据条件来进行逻辑查询,原生的有,ORMLite也有,GreenDao也有,我就拿原生的和GreenDao来做对比
/
原生查询
/
publicvoidqueryNative(){
//查询条件
Stringwhere="wherenamelike?and_id>?";
//使用sql进行查询
Listlist=daoManager.getDaoSession().queryRaw(Student.class,where,
newString[]{"%l%","6"});
Log.i(TAG,list+"");
}

/
QueryBuilder查询大于
/
publicvoidqueryBuilder(){
//查询构建器
QueryBuilderqueryBuilder=daoManager.getDaoSession().queryBuilder(Student.class);
//查询年龄大于19的北京
Listlist=queryBuilder.where(StudentDao.Properties.Age.ge(19)).where(StudentDao.Properties.Address.like("北京")).list();
Log.i(TAG,list+"");
}

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

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

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

packagecom.lgl.greendao;

importandroid.content.Context;
importandroid.util.Log;

importcom.student.dao.StudentDao;
importcom.student.entity.Student;

importjava.util.List;

importde.greenrobot.dao.query.QueryBuilder;

/
完成对某一张表的具体操作
CreatedbyLGLon2016/7/2.
/
publicclassCommonUtils{

//TAG
privatestaticfinalStringTAG=CommonUtils.class.getSimpleName();

privateDaoManagerdaoManager;

//构造方法
publicCommonUtils(Contextcontext){
daoManager=DaoManager.getInstance();
daoManager.initManager(context);
}

/
对数据库中student表的插入操作

@paramstudent
@return
/
publicbooleaninsertStudent(Studentstudent){
booleanflag=false;
flag=daoManager.getDaoSession().insert(student)!=-1?true:false;
returnflag;
}

/
批量插入

@paramstudents
@return
/
publicbooleaninserMultStudent(finalListstudents){
//标识
booleanflag=false;
try{
//插入操作耗时
daoManager.getDaoSession().runInTx(newRunnable(){
@Override
publicvoidrun(){
for(Studentstudent:students){
daoManager.getDaoSession().insertOrReplace(student);
}
}
});
flag=true;
}catch(Exceptione){
e.printStackTrace();
}
returnflag;
}

/
修改

@paramstudent
@return
/
publicbooleanupdateStudent(Studentstudent){
booleanflag=false;
try{
daoManager.getDaoSession().update(student);
flag=true;
}catch(Exceptione){
e.printStackTrace();
}
returnflag;
}

/
删除

@paramstudent
@return
/
publicbooleandeleteStudent(Studentstudent){
booleanflag=false;
try{
//删除指定ID
daoManager.getDaoSession().delete(student);
flag=true;
}catch(Exceptione){
e.printStackTrace();
}
//daoManager.getDaoSession().deleteAll();//删除所有记录
returnflag;
}

/
查询单条

@paramkey
@return
/
publicStudentlistOneStudent(longkey){
returndaoManager.getDaoSession().load(Student.class,key);
}

/
全部查询

@return
/
publicListlistAll(){
returndaoManager.getDaoSession().loadAll(Student.class);
}

/
原生查询
/
publicvoidqueryNative(){
//查询条件
Stringwhere="wherenamelike?and_id>?";
//使用sql进行查询
Listlist=daoManager.getDaoSession().queryRaw(Student.class,where,
newString[]{"%l%","6"});
Log.i(TAG,list+"");
}

/
QueryBuilder查询大于
/
publicvoidqueryBuilder(){
//查询构建器
QueryBuilderqueryBuilder=daoManager.getDaoSession().queryBuilder(Student.class);
//查询年龄大于19的北京
Listlist=queryBuilder.where(StudentDao.Properties.Age.ge(19)).where(StudentDao.Properties.Address.like("北京")).list();
Log.i(TAG,list+"");
}
}
献花(0)
+1
(本文系网络学习天...首藏)