Android数据库高手秘籍(七)

转载请注明出处:

经过了多篇文章的学习,我们已经把LitePal中的绝大部分内容都掌握了。现在回想起来了,增删改查四种操作中的前三种我们都已经学完了,不知道现在使用起数据库来,你有没有感觉到格外的轻松和简单。但是呢,我们都知道,在所有的数据库操作当中,查询操作肯定是最复杂的,用法也是最多的,因此LitePal在查询方面提供的API也是比较丰富,而且LitePal在查询方面的API设计也是颇为艺术的。那么今天我们就专门使用一篇博客来讲解一下查询操作的用法,体验一下LitePal查询的艺术。还没有看过前面一篇文章的朋友建议先去参考 Android数据库高手秘籍(六)——LitePal的修改和删除操作。

LitePal的项目地址是:https://github.com/LitePalFramework/LitePal

传统的查询数据方式

其实最传统的查询数据的方式当然是使用SQL语句了,Android当中也提供了直接使用原生SQL语句来查询数据库表的方法,即SQLiteDatabase中的rawQuery()方法,方法定义如下:

public Cursor rawQuery(String sql, String[] selectionArgs)其中,rawQuery()方法接收两个参数,第一个参数接收的就是一个SQL字符串,第二个参数是用于替换SQL语句中占位符(?)的字符串数组。rawQuery()方法返回一个Cursor对象,所有查询到的数据都是封闭在这个对象当中的,我们只要一一取出就可以了。

当然这种用法其实并不是很常用,因为相信大多数人都还是不喜欢编写SQL语句的。所以,Android专门提供了一种封装好的API,使得我们不用编写SQL语句也能查询出数据,即SQLiteDatabase中的query()方法。query()提供了三个方法重载,其中参数最少的一个也有七个参数,我们来看下方法定义:

public Cursor query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy)

其中第一参数是表名,,表示我们希望从哪张表中查询数据。第二个参数用于指定去查询哪几列,如果不指定则默认查询所有列。第三、第四个参数用于去约束查询某一行或某几行的数据,不指定则默认是查询所有行的数据。第五个参数用于指定需要去group by的列,不指定则表示不对查询结果进行group by操作。第六个参数用于对group by之后的数据进行进一步的过滤,不指定则表示不进行过滤。第七个参数用于指定查询结果的排序方式,不指定则表示使用默认的排序方式。

这个方法是query()方法最少的一个方法重载了,另外还有两个方法重载分别是八个和九个参数。虽说这个方法在Android数据库表查询的时候非常常用,但重多的参数让我们在理解这个方法的时候可能会很费力,另外使用起来的时候也会相当的不爽。比如说,我们想查询news表中的所有数据,就应该要这样写:

SQLiteDatabase db = dbHelper.getWritableDatabase();Cursor cursor = db.query("news", null, null, null, null, null, null);

可以看到,将第一个表名参数指定成news,然后后面的六个参数我们都用不到,就全部指定成null。

那如果是我们想查询news表中所有评论数大于零的新闻该怎么写呢?代码如下所示:

SQLiteDatabase db = dbHelper.getWritableDatabase();Cursor cursor = db.query("news", null, "commentcount>?", new String[]{"0"}, null, null, null);由于第三和第四个参数是用于指定约束条件的,所以我们在第三个参数中指明了commentcount>?,然后在第四个参数中通过一个String数组来替换占位符,这样查到的结果就是news表中所有评论数大于零的新闻了。那么其它的几个参数呢?仍然用不到,所以还是只能传null。

然后我们可以看到,query()方法的返回值是一个Cursor对象,所有查询到的数据都是封装在这个对象中的,所以我们还需要将数据逐一从Cursor对象中取出,然后设置到News实体类当中,如下所示:

List<News> newsList = new ArrayList<News>();if (cursor != null && cursor.moveToFirst()) {do {int id = cursor.getInt(cursor.getColumnIndex("id"));String title = cursor.getString(cursor.getColumnIndex("title"));String content = cursor.getString(cursor.getColumnIndex("content"));Date publishDate = new Date(cursor.getLong(cursor.getColumnIndex("publishdate")));int commentCount = cursor.getInt(cursor.getColumnIndex("commentcount"));News news = new News();news.setId(id);news.setTitle(title);news.setContent(content);news.setPublishDate(publishDate);news.setCommentCount(commentCount);newsList.add(news);} while (cursor.moveToNext());}

这大概就是传统查询数据方式的用法了,总体来看,用法确实非常不友好,尤其是query()方法冗长的参数列表,即使我们用不到那些参数,也必须要传入许多个null。另外,查询到的数据还都只是封装到了一个Cursor对象中,我们还需要将数据一一取出然后再set到实体类对象当中。麻烦吗?可能你觉得不麻烦,因为你已经习惯了这种用法。但是习惯总是可以改变的,也许当你体验了LitePal中查询API给我们带来的便利之后,就会有了新的看法了,那么下面我们就一起来体验一下LitePal的查询艺术。

使用LitePal查询数据

LitePal在查询方面提供了非常丰富的API,功能多种多样,基本上已经能够满足我们平时所有的查询需求了。不仅如此,LitePal在查询API的设计方面也是非常用心,摒弃了原生query()方法中繁琐的参数列表,而是改用了一种更为灵巧的方式——连缀查询。除此之外,LitePal查询的结果也不再返回Cursor对象,然后再由开发者自己去逐个取出,而是直接返回封装好的对象。这些改变都使得查询数据变得更加简单,也更加合理,那么下面我们就来完整地学习一下LitePal中查询数据的所有用法。

简单查询

比如说现在我们想实现一个最简单的功能,查询news表中id为1的这条记录,使用LitePal就可以这样写:

News news = DataSupport.find(News.class, 1);

天呐!有没有觉得太轻松了?仅仅一行代码,就可以把news表中id为1的记录查出来了,而且结果还是自动封装到News对象里的,也不需要我们手动再从Cursor中去解析。如果是用原生的SQL语句,或者query()方法来写,至少要20行左右的代码才能完成同样的功能!

没有口水与汗水,就没有成功的泪水。

Android数据库高手秘籍(七)

相关文章:

你感兴趣的文章:

标签云: