安卓GreenDao框架一些进阶用法整理,安卓greendao
大致分为以下几个方面:
- 一些查询指令整理
- 使用SQL语句进行特殊查询
- 检测表字段是否存在
- 数据库升级
- 数据库表字段赋初始值
一、查询指令整理
1.链式执行的指令
return mDaoSession.getUserDao().queryBuilder(). XXX. XXX. XXX. list();
一般的查询语句会在中间xxx的位置加上各种判断和过滤的方法指令,除了最后的终结指令list()或unique()返回的是集合或业务对象,其他的都是返回QueryBuilder对象,大多数情况下XXX的位置都是填上where语句,还有一些其他和sql关联的语句便于使用。
“whereOr” where语句里面写的条件都是用“且”连接,whereOr里的语句使用“或”连接
“distinct” 直接过滤掉重负字段
“limit” 分页n个一页,一般和offset结合使用
“offset” 忽略查询出的前n条结果
“orderAsc” 以字段升序排序
“orderDesc”以字段降序
“preferLocalizedStringOrder” 本地化字符串排序
“orderCustom” 自定义排序 里面需要传两个参数: 一个属性 和对应的排序方案 ASC 或是 DESC
“orderRaw” 也是自定义排序, 把字段和 排序方案 写在一个字符串传入
“stringOrderCollation” 也是自定义排序 可以合并多个升降排序方案 以日期升序 且 价格降序
2.条件里的指令
return mDaoSession.getUserDao().queryBuilder(). where(UserDao.Properties.UserId.in(userIdList), UserDao.Properties.UserAge.eq(19)). list();
一个简单的where语句大概是这样,在where的括号里面可以并列的写很多条件,其中全部以“且” 来连接。除了上面的“in”和“eq”还有很多其他判断条件
“notEq” 和eq相反,别傻傻在再去外面敲“!”取反
“notIn” 同上
“or” 或者
“like” 就是sql语句的LIKE "%"+string+"%"
“between” 也就是BETWEEN ? AND ? 可以取两个值的区间 (但是这条语句要慎用,不同的数据库不一样,有的是A<条件<B,有的是A<=条件<=B)
“gt” 相当于 >
“ge”相当于 >=
“lt” 相当于 <
“le”相当于 <=
“isNull” 为空
“notIsNull” 不为空
二、使用SQL语句进行特殊查询
一般遇到普通的增删改查操作无法轻易实现的功能,会使用这种rawQuery的方式。 我经常遇到的也就是两种场景:
1.使用SELECT DISTINCT
常用与一对多关系,假设图书馆现在有个“用户存书表” 有的用户有20本书,表里就会有20条他的数据,每条对应一本不同的书。
这时假设有个需求,查出这个表中,所有的用户名字,不许重复。 这时候用普通的查询指令就会非常麻烦了,需要使用SELECT DISTINCT指令查出某列名所有不重复的条目。
String queryString = "SELECT DISTINCT " + UserBookDao.Properties.UserName.columnName + " FROM " + UserBookDao.TABLENAME + " ORDER BY " + UserBookDao.Properties.CreatedTime + " DESC " + " LIMIT " + page * LIMIT_NUM + " , " + LIMIT_NUM; ArrayList<String> result = new ArrayList<>(); Cursor c = mDaoSession.getDatabase().rawQuery(queryString,new String[]{}); try { if (c != null) { if (c.moveToFirst()) { do { result.add(c.getString(0)); } while (c.moveToNext()); } } } finally { if (c != null) { c.close(); } }
大概代码的画风就是这个样子,先拼接出一个符合sql语法的字符串,上面也随机加了一写其他的操作指令字段排序和分页,使得查询指令看上去更加完整,然后使用游标来接收上面的查询结果。
可能大多数查询的时候会带上一些参数,比如where XX = XX 的过滤条件,假设有个需求需要在之前的查询用户需求上加上对出版社和图书价格的限制,则查询方式如下
String queryString = "SELECT DISTINCT " + UserBookDao.Properties.UserName.columnName + " FROM " + UserBookDao.TABLENAME // 董铂然博客园 + " WHERE " + UserBookDao.Properties.Publisher.columnName + " = ?" + " AND " + UserBookDao.Properties.Price.columnName + " > ?" + " ORDER BY " + UserBookDao.Properties.CreatedTime + " DESC "; ArrayList<String> result = new ArrayList<>(); Cursor c = mDaoSession.getDatabase().rawQuery(queryString, new String[]{"某出版社"), String.valueOf(100.00)}); try { if (c != null) { if (c.moveToFirst()) { do { result.add(c.getString(0)); } while (c.moveToNext()); } } } finally { if (c != null) { c.close(); } }
带上参数的查询字符串需要在上面使用问号占位,然后在下面用rawQuery带参数的api里填上相关的入参。
2. SELECT同时查询多个字段
还是用这个查书的例子,假设一下要查“书名”、“出版社”、“价格” 三个字段
String queryString = "SELECT " + UserBookDao.TABLENAME + "." + UserBookDao.Properties.BookName.columnName + "," + UserBookDao.TABLENAME + "." + UserBookDao.Properties.Publisher.columnName + "," + UserBookDao.TABLENAME + "." + UserBookDao.Properties.Price.columnName + " " + "FROM " + UserBookDao.TABLENAME + " " + "WHERE" + UserBookDao.Properties.Price + " > 100.00 "; Cursor cursor = null; try { cursor = session.getDatabase().rawQuery(queryString,new String[]{}); if (cursor == null) { return payMap; } // 取出三个字段分别对应的索引,下面再对着索引去取值 int nameIndex = cursor.getColumnIndex(UserBookDao.Properties.BookName.columnName); int publisherIndex = cursor.getColumnIndex(UserBookDao.Properties.Publisher.columnName); int priceIndex = cursor.getColumnIndex(UserBookDao.Properties.Price.columnName); if (nameIndex != -1 && publisherIndex != -1 && priceIndex != -1) { while (cursor.moveToNext()) { String name = cursor.getString(nameIndex); String publisher = cursor.getString(publisherIndex); Double price = cursor.getDouble(priceIndex); // 这里取到三个字段 自己是存模型还是字典 自己处理。 } } } finally { if (null != cursor) { cursor.close(); } }
下面可以一次性的取出三个所需字段进行使用,需要先得到字段对应索引,然后再对着索引取值。
三、检测表字段是否存在
private boolean hasColumn(SQLiteDatabase db, String tableName, String column) { if (TextUtils.isEmpty(tableName) || TextUtils.isEmpty(column)) { return false; } Cursor cursor = null; try { cursor = db.query(tableName, null, null, null, null, null, null); if (null != cursor && cursor.getColumnIndex(column) != -1) { ret