您的位置:首页 > 移动开发 > Android开发

[Android]GreenDao(2)——使用

2015-08-26 17:08 447 查看
上一篇讲了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
(多次查询)

其他等

这里着重讲
QueryBuilder
Query
,个人用得非常顺手,因为自己对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
就不要随便用了。

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底层并不保证线程安全,这意味着多线程环境下还需要我们程序圆来控制 ;)

源码链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: