美文网首页Android
GreenDao(2)--使用

GreenDao(2)--使用

作者: 豆沙包67 | 来源:发表于2015-08-26 16:40 被阅读3887次

    上一篇讲了GreenDao的配置,本篇着重于API的各种使用,并附上Demo。

    类的关系

    大家还记得上一篇讲到的代码自动生成的四个类,DaoMaster,DaoSession,Dao,User,排除最后一个User实体类不说,其他三个的关系应该是非常明确的。

    类图

    从图上看出,得到User对象的步骤。其中还有些细节需要说明。

    获取DaoMaster

    用过数据库的程序圆都清楚,我们需要DaoSession对象来进行对数据库的增删改查。

    DaoMaster中有newSession()的方法可以帮我们实现。

    所以我们应该先实例化DaoMaster,具体代码是

    public DaoMaster(SQLiteDatabase db) {
        super(db, SCHEMA_VERSION);
        registerDaoClass(UserDao.class);
    }
    

    噢,需要一个SQLiteDatabase实例,请拼命想一想怎么获取一个SQLiteDatabase实例?

    没错,通过SQLiteOpenHelper,再仔细看一下DaoMaster,好像已经提供了抽象类OpenHelper继承了SQLiteOpenHelper

    Cool!

    可以获取DevOpenHelper,具体代码是

         /**
         * WARNING: Drops all table on Upgrade! Use only during development.
         */
        public static class DevOpenHelper extends OpenHelper {
            public DevOpenHelper(Context context, String name, CursorFactory factory) {
                super(context, name, factory);
            }
    
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
                dropAllTables(db, true);
                onCreate(db);
            }
        }
    

    先不管警告的注释(当数据库升级的时候会删除所有表,仅限于开发时使用)。

    只要简单两行代码

     DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
    DaoMaster daoMaster = new DaoMaster(mHelper.getReadableDatabase());
    //也可以使用mHelper.getWritableDatabase();
    

    注意:getReadabledatabase()与getWritableDatabase()其实返回的实例都是一样的,只是当内存空间不足的时候,就不能继续写入数据,更为重要的是,它们都是耗时耗时耗时操作!更为详细的解释

    获取DaoSession

    接着,我们来获取DaoSession

    DaoSession daoSession = daoMaster.newSession();
    //异步查询,异步查询,异步查询
    AsyncSession asyncSession = daoSession.startAsyncSession();
    

    够简单吗?获得DaoSession后可以干什么?其实增删改查的基本功能已经齐全。
    只是有三个缺点:

    • 颗粒度太大
    • API不是很方便
    • 官网注释说只是用于快捷操作

    所以UserDao登场吧

    获取UserDao

    UserDao userDao = daoSession.getUserDao();
    

    好了,下面就可以随心所欲地操作数据库了。

    操作数据库

    /**
     * 插入一个User对象
     *
     * @param user
     * @return 插入对象的列id
     */
    public long insert(User user) {
        UserDao userDao = getUserDao();
        return userDao.insert(user);
    }
    

    查查查***重点

    具体方法有

    • queryXXX(...),指明各种条件
    • 使用QueryBuilder(单次查询),Query(多次查询)
    • 其他等

    这里着重讲QueryBuilderQuery,个人用得非常顺手,因为自己对SQL语句并不喜欢,so...

    看一个简单例子

    /**
     * 通过id取得用户。此处使用QueryBuider,并没有构造Query
     *
     * @param id
     * @return
     */
    public User getUserById(long id) {
        UserDao userDao = getUserDao();
        //获取QueryBuilder
        QueryBuilder qb = userDao.queryBuilder();
        //声明条件,属性在UserDao中已经存在
        qb.where(UserDao.Properties.Id.eq(id));
        //返回唯一数据
        return (User) qb.unique();
    }
    

    QueryBuilder只是用来创建Query而已,Query更使用于相同的查询,所以QueryBuilder就不要随便用了。

    Quert特点如下

    • Query通过QueryBuilder.build()获取,它是使用Builder模式设计的,支持多次查询多线程查询

        //实际按照要求具体操作
        Query<User> query = userDao.queryBuilder().orderDesc().where().count().build();
        //返回单一结果
        query.unique()
        //返回一个非null的实体。否则就会抛出一个DaoException。
        query.uniqueOrThrow()
        //所有查询都加载到内存
        query.list();
        //实体按照需求加载进入内存。一旦列表中的一个元素被第一次访问,它将被加载同时缓存以便以后使用。必须close。
        query.listLazy();
        //多线程查询,为当前线程获取一个Query实例
        query.forCurrentThread();
      
    • 支持equal,in,between等等一系列比较符

    • Query可重用

    先创建如下Query,根据id = 123和age = 10进行查找(示例)

        UserDao userDao = getUserDao();
        QueryBuilder<User> queryBuilder = userDao.queryBuilder().where(UserDao.Properties.Id.eq(123));
        queryBuilder.where(UserDao.Properties.Age.eq(10)).unique();
        Query query = queryBuilder.build();
        query.unique();
    

    下一次同样需要根据id = 321和age = 100来进行查找,就可以

    //设置id和age的值
    query.setParameter(321, 100);
    //返回唯一结果
    //query.unique()
    //设置多个查找目标
    query.setParameter(111, 180);
    //返回list
    query.list();
    

    注意:当Query没有返回语气结果,故障排查可以设置QueryBuilder.LOG_SQL = true;QueryBuilder.LOG_VALUES = true;,打印出SQL语句

    更多高级用法请查看官方API文档

    基本原则是根据主键来修改,比较简单的两种情况是

    • 已知主键

    直接能用API的都基本上已知主键的

        /**
         * 更新user信息
         *
         * @param newUser 新User,主键必须存在
         */
        public void update(User newUser) {
            UserDao userDao = getUserDao();
            userDao.update(newUser);
        }
    
    • 未知主键,知道其他值

    先根据主键查找(复习查找的知识),再重复情况一

    同理,跟改操作基本一致。

       /**
         * 根据主键删除User
         *
         * @param id User的主键Id
         */
        public void deleteUserById(long id) {
            UserDao userDao = getUserDao();
            userDao.deleteByKey(id);
        }
    

    总结

    GreenDao给我们简化了编写大量重复代码的步骤,作为轻量级的ORM框架速度飞快,值得深入学习。

    GreenDao底层并不保证线程安全,这意味着多线程环境下还需要我们程序圆来控制 ;)

    源码戳这里

    相关文章

      网友评论

      本文标题:GreenDao(2)--使用

      本文链接:https://www.haomeiwen.com/subject/qmtqcttx.html