上一篇讲了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
就不要随便用了。
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底层并不保证线程安全,这意味着多线程环境下还需要我们程序圆来控制 ;)
网友评论