全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

安卓GreenDao框架一些进阶用法整理

大致分为以下几个方面:

  1. 一些查询指令整理
  2. 使用SQL语句进行特殊查询
  3. 检测表字段是否存在
  4. 数据库升级
  5. 数据库表字段赋初始值

一、查询指令整理

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) {
  return true;
 }
 } finally {
 if (null != cursor) {
  cursor.close();
 }
 }
 return false;
}

和上面取游标的方式类似,取出的列索引值如果不是-1,则代表能够取到这个字段返回true,否则和入参非法一起返回fasle。

四、数据库升级

这边会调用上面判断列名是否已经存在的方法。

然后重写父类的这个onUpgrade方法

private static class DemoOpenHelper extends DaoMaster.OpenHelper {
 public DemoOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
 super(context, name, factory);
 }
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 // 数据库的版本控制 可以随着版本叠加不断增加差值
 if (oldVersion < 2) {
  if (!hasColumn(db, UserBookDao.TABLENAME, UserBookDao.Properties.Author.columnName)) {
  String sql = "alter table " + UserBookDao.TABLENAME +
   " add COLUMN " + UserBookDao.Properties.Author.columnName + " TEXT";
  db.execSQL(sql);
  }
  if (!hasColumn(db, UserBookDao.TABLENAME, UserBookDao.Properties.Type.columnName)) {
  String sql = "alter table " + UserBookDao.TABLENAME +
   " add COLUMN " + UserBookDao.Properties.Type.columnName + " INTEGER";
  db.execSQL(sql);
  }
 }
 }
}

除了上面的修改表,如果改动太多或是换了表明,还可以直接删了重建(这么做的话之前的数据也就删了)

if (oldVersion < 3) {
 UserDao.dropTable(new StandardDatabase(db),true);
 UserStudentDao.createTable(new StandardDatabase(db),true);
}

五、数据库表字段赋初始值

有些字段的初始值如果你不希望是0,或是空字符串,可以赋初始值。现在的赋值初始值就分为两种情况了

1.建表时附初始值

在3.0以前的版本 还是要写一个module,里面写类似代码来建表的

private static void addUser(Schema schema) {
 Entity user = schema.addEntity("User");
 user.addIdProperty();
 user.addStringProperty("name").notNull().defValue("\"jack\"");
 user.addStringProperty("address");
 user.addStringProperty("teacher");
 user.addIntProperty("age").primJavaType().defValue("17");
}

在3.0之后推行用注解和直接写Entity的写法,所以可以直接在Entity的类里指定

@Entity
public class Student {
 @Id(autoincrement = true)
 private long id; //主键
 private String name;
 private String schoolTime = "09-01"; //开学时间默认都是9月1日
 private int age = 19; // 刚上大学的默认都是19岁
 // 下面生成的getter 和setter省略 。。。
}

2.数据库升级时给升级字段赋初始值

上面说的的数据库升级,是需要写一条alter table的sql语句,可以直接拼接到这一行后面

// 上面判断该列名是否存在
// ...
String sql = "alter table " + UserBookDao.TABLENAME +
 " add COLUMN " + UserBookDao.Properties.Type.columnName + " INTEGER" + " NOT NULL DEFAULT(-1) "; // 直接拼接在语句最后 董铂然博客园
db.execSQL(sql);
// ...

注:以前听过一种说法是直接在UserDao这种生成的类里直接在生成的创建语句后面拼接DEFAULT,这里非常反对, 首先人家类名明确表明 // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.  并且有些人的代码可能设置的是手动生成,但我们的项目就在gradle里设置了每次build都会先自动生成一下,这种情况每次都会覆盖。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# GreenDao  # 框架  # GreenDao 3.2.0 的基本使用  # 都是  # 有个  # 自定义  # 的是  # 升序  # 是否存在  # 多个  # 两种  # 其他的  # 可以直接  # 分页  # 链式  # 删了  # 有的是  # 为空  # 填上  # 就会  # 博客园  # 降序  # 就在 


相关文章: 实现点击下箭头变上箭头来回切换的两种方法【推荐】  油猴 教程,油猴搜脚本为什么会网页无法显示?  网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?  北京制作网站的公司,北京铁路集团官方网站?  如何快速搭建高效WAP手机网站吸引移动用户?  攀枝花网站建设,攀枝花营业执照网上怎么年审?  如何解决VPS建站LNMP环境配置常见问题?  如何用景安虚拟主机手机版绑定域名建站?  网站制作员失业,怎样查看自己网站的注册者?  网站制作大概多少钱一个,做一个平台网站大概多少钱?  济南网站建设制作公司,室内设计网站一般都有哪些功能?  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  如何打造高效商业网站?建站目的决定转化率  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  营销式网站制作方案,销售哪个网站招聘效果最好?  如何构建满足综合性能需求的优质建站方案?  建站主机如何选?性能与价格怎样平衡?  如何通过山东自助建站平台快速注册域名?  如何快速生成凡客建站的专业级图册?  番禺网站制作公司哪家值得合作,番禺图书馆新馆开放了吗?  济南网站制作的价格,历城一职专官方网站?  云南网站制作公司有哪些,云南最好的招聘网站是哪个?  如何实现建站之星域名转发设置?  linux top下的 minerd 木马清除方法  如何确认建站备案号应放置的具体位置?  宝塔新建站点报错如何解决?  公众号网站制作网页,微信公众号怎么制作?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  已有域名和空间如何快速搭建网站?  高防服务器如何保障网站安全无虞?  如何快速搭建支持数据库操作的智能建站平台?  七夕网站制作视频,七夕大促活动怎么报名?  制作网站公司那家好,网络公司是做什么的?  制作证书网站有哪些,全国城建培训中心证书查询官网?  如何选择高效响应式自助建站源码系统?  如何在万网ECS上快速搭建专属网站?  再谈Python中的字符串与字符编码(推荐)  网站代码制作软件有哪些,如何生成自己网站的代码?  如何确保FTP站点访问权限与数据传输安全?  建站之星安装后界面空白如何解决?  如何设计高效校园网站?  宁波自助建站系统如何快速打造专业企业网站?  如何获取免费开源的自助建站系统源码?  完全自定义免费建站平台:主题模板在线生成一站式服务  网站企业制作流程,用什么语言做企业网站比较好?  如何快速打造个性化非模板自助建站?  建站之星微信建站一键生成小程序+多端营销系统  建站主机是否等同于虚拟主机?  网站制作网站,深圳做网站哪家比较好?  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。