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


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


    这里写图片描述

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

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

    这里写图片描述

    一.相关介绍

    传说中的优点

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

    这里写图片描述

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

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

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

    同时也要添加java的项目包

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

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

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

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

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

    compile 'org.greenrobot:greendao-generator:2.2.0'
    • 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

    写完这个时候我们要注意了,我们不能直接去运动这个工程,我们要单独编译这个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

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

    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

    五.插入

    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

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

      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

    我们一运行之后,就可以在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

    我们可以去验证一下吧,那首先先去写一个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

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

             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

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

    这里写图片描述

    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

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

         <Button
            android:id="@+id/btn_update"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="修改一条数据" />
    • 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

    很好,很强势,我们导出数据库,看看有没有修改成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

    这样就写个按钮

        <Button
            android:id="@+id/btn_delete"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="删除一条数据" />
    • 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

    我们要删除的是他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

    我们再定义一个button

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

    这样我们就可以去查询了

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

    十.全部查询

    全部查询比较简单

        /**
         * 全部查询
         *
         * @return
         */
        public List<Student> listAll() {
            return daoManager.getDaoSession().loadAll(Student.class);
        }
    • 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

    十一.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

    不难看出,使用起来是比较方便的,我们可以无限的加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

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

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

  • 相关阅读:
    c++求最大公约数、最小公倍数
    五个简单的shell脚本
    微信小程序slot(一)
    小程序详解子传父
    小程序封装组件详解父传子
    小程序生命周期详解
    小程序之confirm-type改变键盘右下角的内容和input按钮详解
    小程序之按钮你不知道的v2
    小程序image图片缩小不变形
    小程序之navigator跳转方式
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/9629067.html
Copyright © 2020-2023  润新知