上一篇讲了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);//返回listquery.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底层并不保证线程安全,这意味着多线程环境下还需要我们程序圆来控制 ;)
源码链接
版权声明:本文为博主原创文章,未经博主允许不得转载。