安卓GreenDao框架一些进阶用法整理
作者:董铂然 发布时间:2023-06-17 03:27:21
大致分为以下几个方面:
一些查询指令整理
使用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) {
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都会先自动生成一下,这种情况每次都会覆盖。
来源:http://www.cnblogs.com/dsxniubility/p/6204169.html
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- 使用AS创建ADIL文件时AS会在main文件夹下给我们生成一个aidl文件夹和一个相同包名的包,通常我们会把所有和ADIL相关的类或文件放
- 前言不得不说SpringBoot的开发者是在为大众程序猿谋福利,把大家都惯成了懒汉,xml不配置了,连tomcat也懒的配置了,典型的一键启
- LinkedList与ArrayList都是List接口的具体实现类。LinkedList与ArrayList在功能上也是大体一致,但是因为
- 在"C#中,什么时候用yield return"中,我们了解到:使用yield return返回集合,不是一次性加载到内
- 本文实例讲述了从C#程序中调用非受管DLLs的方法。分享给大家供大家参考。具体方法如下:前言:从所周知,.NET已经渐渐成为一种技术时尚,那
- 一问道StringBuffer与StringBuilder的区别,张口就来StringBuffer是线程安全的,因为它相关方法都加了sync
- 本文实例讲述了java可变参数当做数组处理的方法.分享给大家供大家参考,具体如下:java可变参数当做数组处理ava1.5增加了新特性:可变
- 记得上学的时候学习英语,每个英语老师说到英语翻译的时候都会说英语翻译要做到“信、达、雅”。如今做了一名程序员竟然体会我还是想用这三种境界来要
- 本篇文章主要介绍了详解Xamarin.Android 利用Fragment实现底部菜单,分享给大家,具体如下:效果图:第一步:添加引用引用
- 最近在做wifi的相关的东西,打印WifiInfo的时候 无意间发现一个参数,改参数可以查看是否连接成功了指定wifi,但是这是隐藏的,遂将
- 本文实例讲述了Android使用SharedPreferences存储数据的实现方法。分享给大家供大家参考,具体如下:编辑短信的时候,突然接
- 下载IDEA插件IDEA插件选择版本号下载与IDEA版本号相近的插件打开IDEA,导入下载好的插件在File下找到setting在Plugi
- 在android6.0之后谷歌对指纹识别进行了官方支持,今天还在放假,所以就随意尝试了一下这个api,但是遇到了各种各样的问题 ①
- 本文实例讲述了C#简单读取、改变文件的创建、修改及访问时间的方法。分享给大家供大家参考。具体如下:FileInfo fi = new Fil
- 本文实例讲述了C#通过WIN32 API实现嵌入程序窗体的方法,分享给大家供大家参考。具体如下:这是一个不使用COM,而是通过WIN32 A
- 正则表达式 是一种匹配输入文本的模式。.Net 框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符和结构组成。接下来通过本
- 参考资料《Java 编程思想》,关于含有基类的导出类,其成员的初始化过程是一个容易让人困惑的地方,下面通过具体的实例进行讲解,代码取自《Ja
- 本文以实例形式讲述了C#解析JSON的方法,C#封装了对XML和JSON解析的类库,使用相当方便!具体用法如下:1.主要用到的类:主要用到了
- The error simply says, “you've made changes in files in your works
- 一.以springboot为例,建立代码1.IExecCommandServer:public interface IExecCommand