GreenDao 3.X之基本使用

GreenDao 3.X之注解已经了解到GreenDao 3.0的改动及注解。对于数据库的操作,无异于增删改查等四个操作。下面我们将了解GreenDao 3.X如何使用?

AbstractDao

所有的自动生成的XXDao都是继承于AbstractDao,此类中基本上封装了所有的增删改操作,包括数据库的事务操作。常用的API如下:

    void     attachEntity(T entity):

    long     count():获取数据库中数据的数量

    // 数据删除相关
    void     delete(T entity):从数据库中删除给定的实体
    void     deleteAll() :删除数据库中全部数据
    void     deleteByKey(K key):从数据库中删除给定Key所对应的实体
    void     deleteByKeyInTx(java.lang.Iterable<K> keys):使用事务操作删除数据库中给定的所有key所对应的实体
    void     deleteByKeyInTx(K... keys):使用事务操作删除数据库中给定的所有key所对应的实体
    void     deleteInTx(java.lang.Iterable<T> entities):使用事务操作删除数据库中给定实体集合中的实体
    void     deleteInTx(T... entities):使用事务操作删除数据库中给定的实体

    // 数据插入相关
    long     insert(T entity):将给定的实体插入数据库
    void     insertInTx(java.lang.Iterable<T> entities):使用事务操作,将给定的实体集合插入数据库
    void     insertInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey):使用事务操作,将给定的实体集合插入数据库,
                                                                                                                    并设置是否设定主键
    void     insertInTx(T... entities):将给定的实体插入数据库
    long     insertOrReplace(T entity):将给定的实体插入数据库,若此实体类存在,则覆盖
    void     insertOrReplaceInTx(java.lang.Iterable<T> entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖
    void     insertOrReplaceInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖
                                                                                                                                并设置是否设定主键
    void     insertOrReplaceInTx(T... entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖
    long     insertWithoutSettingPk(T entity):将给定的实体插入数据库,但不设定主键

    // 新增数据插入相关API
    void     save(T entity):将给定的实体插入数据库,若此实体类存在,则更新
    void     saveInTx(java.lang.Iterable<T> entities):将给定的实体插入数据库,若此实体类存在,则更新
    void     saveInTx(T... entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则更新

    // 加载相关
    T     load(K key):加载给定主键的实体
    java.util.List<T>     loadAll():加载数据库中所有的实体
    protected java.util.List<T>     loadAllAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回实体的列表,并关闭该cursor
    protected java.util.List<T>     loadAllFromCursor(android.database.Cursor cursor):从cursor中读取、返回实体的列表
    T     loadByRowId(long rowId) :加载某一行并返回该行的实体
    protected T     loadUnique(android.database.Cursor cursor) :从cursor中读取、返回唯一实体
    protected T     loadUniqueAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回唯一实体,并关闭该cursor

    //更新数据
    void     update(T entity) :更新给定的实体
    protected void     updateInsideSynchronized(T entity, DatabaseStatement stmt, boolean lock)
    protected void     updateInsideSynchronized(T entity, android.database.sqlite.SQLiteStatement stmt, boolean lock)
    void     updateInTx(java.lang.Iterable<T> entities) :使用事务操作,更新给定的实体
    void     updateInTx(T... entities):使用事务操作,更新给定的实体

QueryBuilder、Query

基本查询

GreenDao中,使用QueryBuilder自定义查询实体,而不是再写繁琐的SQL语句,避免了SQL语句的出错率。大家都知道写SQL语句时,非常容易出错,出错后又十分的难查。QueryBuilder真是帮忙解决了一个大麻烦。具体该如何使用呢?

    List joes = userDao.queryBuilder()
                       // 查询的条件
                       .where(Properties.FirstName.eq("Joe"))
                       // 返回实体集合升序排列
                       .orderAsc(Properties.LastName)
                       .list();
    QueryBuilder qb = userDao.queryBuilder();
    // 查询的条件
    qb.where(Properties.FirstName.eq("Joe"),
    qb.or(Properties.YearOfBirth.gt(1970),
    qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));
    List youngJoes = qb.list();    </span>

上面是官方给出的两个列子,不仅满足了查询语句的易写,同时使用了流式写法,提高了代码的可阅读性。

Limit、Offset、Pagination

在实际开发过程中,大家肯定碰到这样的问题,当数据过多在一页显示不出来的时候,要么选择前面十条显示,要么分页显示,但是数据总是获取全部的。其实,刚接触GreenDao的时候,也是这么干,获取全部的实体集合,然后再根据实际情况截取。看了API以后,豁然开朗,大神们已经帮我们解决了这件事。此时不得不说,QueryBuilder
中的Limit(限制)、Offset(偏移),limit(int)和offset(int)协同设置,可以完美解决分页显示。

        limit(int):限制查询返回结果的数目
        offset(int):设置查询结果的偏移量,此查询需与limit(int)结合使用,而不能够脱离limit(int)单独使用

Query

当执行多次查询时,实际是QueryBuilder多次调用Query类。如果执行多次相同的查询,应使用QueryBuilder的build()方法来创建Query,而不是直接使用Query类。如果查询返回的结果是唯一性的,可以使用操作符方法,如果不希望此唯一性不返回 null,此时可调用uniqOrThrow()方法。如果查询返回的结果是多个,可以使返回的结果是一个集合,有如下方法:

list():所有实体加载至内存,结果通常是一个ArrayList
listLazy():实体在需要时,加载至内存,表中的第一个元素被第一次访问时会被缓存,下次访问时,使用缓存
listLazyUncached():任何对列表实体的访问懂事从数据库中加载
listIterator():以按需加载的方式来遍历结果,数据没有被缓存  

一旦使用QueryBuilder创建了一个query,那么这个Query对象就可以就可以被复用来执行查询显然这种方式逼重新创建一次Query效率要高。
        具体来说:

如果Query的参数没有变更,你只需要再次调用List/unuque方法即可
如果参数发生了变化,那么就需要通过setParameter方法来处理每一个发生改变的参数  

举例:

Query query = userDao.queryBuilder().where(Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970)).build();
List joesOf1970 = query.list();  

现在复用该Query对象:

query.setParameter(0, "Maria");
query.setParameter(1, 1977);
List mariasOf1977 = query.list();  

由此可见,Query在执行一次build之后会将查询结果进行缓存,方便下次继续使用。

执行原生SQL语句

两种方法:

Query query = userDao.queryBuilder().where(
new StringCondition("_ID IN " +
"(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();  

如果这里的QueryBuilder没有提供你想要的特性,可以使用原始的queryRaw或queryRawCreate方法。

Query query = userDao.queryRawCreate(  ", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID", "admin"

注:写SQL语句时推荐定义常量来表示表名或者表项,这样可以防止出错,因为编译器会检查

基本使用

创建实体类

@Entity(generateConstructors = false)
public class Student {
    @Id
    private Long id;
    private String name;
    private int age;

    public Student() {
    }

    @Keep
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Keep
    public Long getId() {
        return id;
    }

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

    @Keep
    public String getName() {
        return name;
    }

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

    @Keep
    public int getAge() {
        return age;
    }

    @Keep
    public void setAge(int age) {
        this.age = age;
    }

    @Keep
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;

        Student student = (Student) o;

        return name.equals(student.name);

    }

    @Keep
    @Override
    public int hashCode() {
        return (int) (id ^ (id >>> 32));
    }

    @Keep
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}

创建完实体类后,Rebuild Project生成DaoMaster、DaoSession。DaoMaster、DaoSession位于在Gradle设置的目录及文件夹里。

创建Database管理类

public class DbManager {  

    // 是否加密
    public static final boolean ENCRYPTED = true;  

    private static final String DB_NAME = "tea.db";
    private static DbManager mDbManager;
    private static DaoMaster.DevOpenHelper mDevOpenHelper;
    private static DaoMaster mDaoMaster;
    private static DaoSession mDaoSession;  

    private Context mContext;  

    private DbManager(Context context) {
        this.mContext = context;
        // 初始化数据库信息
        mDevOpenHelper = new DaoMaster.DevOpenHelper(context, DB_NAME);
        getDaoMaster(context);
        getDaoSession(context);
    }  

    public static DbManager getInstance(Context context) {
        if (null == mDbManager) {
            synchronized (DbManager.class) {
                if (null == mDbManager) {
                    mDbManager = new DbManager(context);
                }
            }
        }
        return mDbManager;
    }  

    /**
     * @desc 获取可读数据库
     * @autor Tiany
     * @time 2016/8/13
     **/
    public static SQLiteDatabase getReadableDatabase(Context context) {
        if (null == mDevOpenHelper) {
            getInstance(context);
        }
        return mDevOpenHelper.getReadableDatabase();
    }  

    /**
     * @desc 获取可写数据库
     * @autor Tiany
     * @time 2016/8/13
     **/
    public static SQLiteDatabase getWritableDatabase(Context context) {
        if (null == mDevOpenHelper) {
            getInstance(context);
        }
        return mDevOpenHelper.getWritableDatabase();
    }  

    /**
     * @desc 获取DaoMaster
     * @autor Tiany
     * @time 2016/8/13
     **/
    public static DaoMaster getDaoMaster(Context context) {
        if (null == mDaoMaster) {
            synchronized (DbManager.class) {
                if (null == mDaoMaster) {
                    mDaoMaster = new DaoMaster(getWritableDatabase(context));
                }
            }
        }
        return mDaoMaster;
    }  

    /**
     * @desc 获取DaoSession
     * @autor Tiany
     * @time 2016/8/13
     **/
    public static DaoSession getDaoSession(Context context) {
        if (null == mDaoSession) {
            synchronized (DbManager.class) {
                mDaoSession = getDaoMaster(context).newSession();
            }
        }  

        return mDaoSession;
    }
}
数据库操作类
[java] view plain copy
public class StudentDaoOpe {  

    /**
     * @desc 添加数据至数据库
     * @autor Tiany
     * @time 2016/8/13
     **/
    public static void insertData(Context context, Student stu) {  

        DbManager.getDaoSession(context).getStudentDao().insert(stu);
    }  

    /**
     * @desc 将数据实体通过事务添加至数据库
     * @autor Tiany
     * @time 2016/8/13
     **/
    public static void insertData(Context context, List<Student> list) {
        if (null == list || list.size() <= 0) {
            return;
        }
        DbManager.getDaoSession(context).getStudentDao().insertInTx(list);
    }  

    /**
     * @desc 添加数据至数据库,如果存在,将原来的数据覆盖
     * @autor Tiany
     * @time 2016/8/15
     **/
    public static void saveData(Context context, Student student) {
        DbManager.getDaoSession(context).getStudentDao().save(student);
    }  

    /**
     * @desc 查询所有数据
     * @autor Tiany
     * @time 2016/8/15
     **/
    public static List<Student> queryAll(Context context) {
        QueryBuilder<Student> builder = DbManager.getDaoSession(context).getStudentDao().queryBuilder();  

        return builder.build().list();
    }
}  

到此为止,数据库的基本操作已完成,根据实际需求笤俑数据库操作类相应的操作即可。

现流行RxJava异步及流式开发,GreenDao已将RxJava集成,具体的使用见

参考文档

1、官方文档

2.、GreenDAO 3.0 初次使用

时间: 2024-12-10 20:45:06

GreenDao 3.X之基本使用的相关文章

GreenDao开源ORM框架浅析

Android程序开发中,避免不了要用到数据库,我们都知道android提供了内置的Sqlite,即调用SQLiteOpenHelper的方法,来操作数据库,但是使用过程较为繁琐,从建表到对表中数据的正删改查操作,需要大量的代码来建立表,和完成这些操作. GreenDao居然是ORM框架,它跟hibernate是很像的,就是当你配置了一些参数信息之后,可以由框架来帮你生成对应的实体类,还有生成对应的操作实体类的代码(自动建表和基本的增删改查). 优点: 1.最大性能(最快的Android ORM

&lt;Android开源库&gt; GreenDAO 用法详解&lt;译文&gt;

简介 greenDAO是一个开源的Android ORM,使SQLite数据库的开发再次变得有趣. 它减轻了开发人员处理底层的数据库需求,同时节省开发时间. SQLite是一个很不错的关系型数据库. 尽管如此,编写SQL和解析查询结果仍然是相当乏味和耗时的任务. greenDAO通过将Java对象映射到数据库表(称为ORM,"对象/关系映射")来解决这些问题. 这样,您可以使用简单的面向对象的API来存储,更新,删除和查询Java对象. 特性 最高性能(可能是Android中最快的OR

MVP+Dagger2+Rxjava+Retrofit+GreenDao 开发的小应用,包含新闻、图片、视频3个大模块,代码封装良好

练习MVP架构开发的App,算是对自己学过的知识做一个总结,做了有一段时间,界面还算挺多的,代码量还是有的,里面做了大量封装,整体代码整理得很干净,这个我已经尽力整理了.不管是文件(java.xml.资源文件)命名,还是布局设计尽量简单简洁,我对自己写代码的规范还是有信心的- -.代码不会写的很复杂,整个代码结构有很高的统一度,结构也比较简单清晰,方便理解.里面做了大量的封装,包括基类的构建和工具类的封装,再配合Dagger2的使用可以极大地减轻V层(Activity和Fragment)的代码,

[转]Android ORM系列之GreenDao最佳实践

GreenDAO是一个可以帮助Android开发者快速将Java对象映射到SQLite数据库的表单中的ORM解决方案,通过使用一个简单的面向对象API,开发者可以对Java对象进行存储.更新.删除和查询. GreenDao有两个项目,一个是生成dao和model的generator的项目,该项目是java项目,一个是用于android的核心jar包.在使用前,我们必须先生成dao和model. 首先加入依赖. compile 'de.greenrobot:greendao:2.0.0' comp

Android 配置使用 GreenDao 教程

?GreenDao介绍 android开发的本地数据库存储是sqlite.greenDAO应该算是当前最火的数据库开源框架了吧,它是一个移动开发的ORM(object / relational mapping)框架,是对sqlite数据库访问的对象化封装.以对象的形式去访问数据库,数据库表里面的字段就相当于对象的属性了.可以直接obj.data的形式访问了.如果觉得效率不够高,你也可以自己ORM的框架.据我所致GreeDao是android开发性能最好的数据库开源框架. 总之,一句话,green

《Andorid开源》greenDao 数据库orm框架

一 前言:以前没用框架写Andorid的Sqlite的时候就是用SQLiteDatabase ,SQLiteOpenHelper ,SQL语句等一些东西,特别在写SQL语句来进行 数据库操作的时候是一件很繁琐的事情,有时候没有错误提示的,很难找到错误的地方,即费力又花时间. 现在使用greenDao就可以避免那些繁琐的SQL文了,极大的简化了对Sqlite的操作. greenDao官方网址是:http://greendao-orm.com/ greenDao官方demo下载地址:https://

greenDao android开源框架数据库更新表的问题

最近使用greenDao当android应用升级数据库新增表或者修改表,发现数据被清空的问题 查找资料也没有找到解决方案,最后查看代码发现需要自己修改SQLiteOpenHelper 1.找到greenDao生成的DaoMaster.java文件,里面有SQLiteOpenHelper实现 2.修改DevOpenHelper类里的   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 方法 通过old

开源框架GreenDao的操作

1.为什么需要GreenDao?Google原生API不方便 @1手动组拼SQL语句 @2需要自己写操作数据库代码 @3不能把数据库中的数据映射成对象 @4没有实现关联查询 2.GreenDao是什么? 开源的数据库操作框架,让操作数据库变为操作对象 3.GreenDao的优点? @1让业务代码访问对象,而不是操作数据库表 @2隐藏了面向对象的逻辑SQL查询详情 @3无须处理数据库实现 4.ANDROID主流ORM框架 @1 OrmLite @2 SugarORM @3 LitePal @4 G

greenDao配置

直接上图:外部的build.gradle只配置一项: classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0' 然后在app内的build.gradle配置三个地方: 1. apply plugin: 'org.greenrobot.greendao'2.greendao { schemaVersion 1 //数据库版本号 daoPackage 'com.xxx.greendao.gen' //com.xxx.greendao为包名,gen

android高效ORM数据库框架greenDao使用

     因为项目中多处用到了数据库,需要对数据库频繁的读写操作,虽然android 自带的SQLiteOpenHelper的.这种方式比较方便易懂,但是在使用过程中需要写很多的sql语句,而且需要及时的关闭和释放资源,使用起来相对复杂,鉴于性能的考虑,决定采用一种ORM框架来解决,     在android中开源的数据库ORM解决方案中.主要有那么几种.综合各方面评价,觉得greenDao相对来说是一个综合考量最好的方案,所以决定试一下,     但是greenDao使用相关资料网上确实不多,