Android数据库(SQLite)框架(6)——使用LitePal查询

来源:互联网 发布:mac怎么打开微博故事 编辑:程序博客网 时间:2024/06/05 04:30

使用LitePal查询数据

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


简单查询

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

Person person = DataSupport.find(Person .class, 1);  

find()方法只接收两个参数,第一个参数是一个泛型类,也就是说我们在这里指定什么类,返回的对象就是什么类,所以这里传入Person .class,那么返回的对象也就是Person 了。第二个参数就更简单了,就是一个id值,如果想要查询id为1的记录就传1,想查id为2的记录就传2,以此类推。

查找第一条记录 : findFirst(Person .class)

LitePal给我们提供了一个更简便的方法——findAll(),用来查询多条数据。这个方法的用法和find()方法是非常类似的,只不过它可以指定多个id,并且返回值也不再是一个泛型类对象,而是一个泛型类集合,如下所示:

假设我们想把person表中id为1、3、5、7的数据都查出来,代码如下:

List<Person > personList = DataSupport.findAll(Person .class, 1, 3, 5, 7);  

首先我们是调用的findAll()方法,然后这个方法的第一个参数仍然是指定的泛型类,但是后面的参数就很随意了,你可以传入任意个id进去,findAll()方法会把所有传入的id所对应的数据全部查出来,然后一起返回到List这个泛型集合当中。

虽说这个语法设计算是相当人性化,但是在有些场景或许不太适用,因为可能要你要查询的多个id已经封装到一个数组里了。那么没关系,findAll()方法也是接收数组参数的,所以说同样的功能你也可以这样写:

long[] ids = new long[] { 1, 3, 5, 7 };  List<Person > personList = DataSupport.findAll(Person .class,ids);  

看到这里,那有的朋友可能会奇怪了,说findAll()方法不应该是查询所有数据的意思吗?怎么总是查询几个id所对应数据呢?哈!这个问题问得好,因为findAll()方法也是可以查询所有数据的,而且查询所有数据的写法更简单,只需要这样写:

List<Person > personList = DataSupport.findAll(Person .class);  

连缀查询

为了避免冗长的参数列表,LitePal采用了一种非常巧妙的解决方案,叫作连缀查询,这种查询很灵活,可以根据我们实际的查询需求来动态配置查询参数。 那这里举个简单的例子,比如我们想查询person表中所有id大于1的用户,就可以这样写:

List< Person > personList = DataSupport.where("id> ?", "1").find(Person.class);  

首先是调用了DataSupport的where()方法,在这里指定了查询条件。where()方法接收任意个字符串参数,其中第一个参数用于进行条件约束,从第二个参数开始,都是用于替换第一个参数中的占位符的。那这个where()方法就对应了一条SQL语句中的where部分。

但是这样会将person表中所有的列都查询出来,也许你并不需要那么多的数据,而是只要name和age这两列数据。那么也很简单,我们只要再增加一个连缀就行了,如下所示:

List< Person > personList = DataSupport.select("name", "age") .where("id> ?", "1").find(Person.class);  

可以看到,这里我们新增了一个select()方法,这个方法接收任意个字符串参数,每个参数要求对应一个列名,这样就只会把相应列的数据查询出来了,因此select()方法对应了一条SQL语句中的select部分。

还可以进行排序查询:

List< Person > personList = DataSupport.select("name", "age") .where("id> ?", "1").order("id desc").find(Person.class); 

也许你并不希望将所有条件匹配的结果一次性全部查询出来,因为这样数据量可能会有点太大了,而是希望只查询出前10条数据,那么使用连缀同样可以轻松解决这个问题,代码如下所示:

List< Person > personList = DataSupport.select("name", "age") .where("id> ?", "1").order("id desc").limit(10).find(Person.class); 

那么现在我想对新闻进行分页展示,翻到第二页时,展示第11到第20条数据,这又该怎么实现呢?没关系,在LitePal的帮助下,这些功能都是十分简单的,只需要再连缀一个偏移量就可以了,如下所示:

List< Person > personList = DataSupport.select("name", "age") .where("id> ?", "1").order("id desc").limit(10).offset(10).find(Person.class); 

激进查询

上述我们的所有用法中,都只能是查询到指定表中的数据而已,关联表中数据是无法查到的,因为LitePal默认的模式就是懒查询,当然这也是推荐的查询方式。那么,如果你真的非常想要一次性将关联表中的数据也一起查询出来,当然也是可以的,LitePal中也支持激进查询的方式。

刚才我们所学的每一个类型的find()方法,都对应了一个带有isEager参数的方法重载,这个参数相信大家一看就明白是什么意思了,设置成true就表示激进查询,这样就会把关联表中的数据一起查询出来了。

List< Person > personList = DataSupport.find(Person.class, 1, true);List<Comment> commentList = personList . getCommentList();

激进查询的用法非常简单,就只有这么多,其它find()方法也都是同样的用法,就不再重复介绍了。但是这种查询方式LitePal并不推荐,因为如果一旦关联表中的数据很多,查询速度可能就会非常慢。而且激进查询只能查询出指定表的关联表数据,但是没法继续迭代查询关联表的关联表数据。因此,这里我建议大家还是使用默认的懒加载更加合适,至于如何查询出关联表中的数据,其实只需要在模型类中做一点小修改就可以了。

修改Person类中的代码,如下所示:

public class Person extends DataSupport{      ...     public List<Comment> getCommentList() {        return DataSupport.where("id = ?",String.valueOf(id)).find(Comment.class);    }}  

可以看到,我们在News类中添加了一个getComments()方法,而这个方法的内部就是使用了一句连缀查询,查出了当前这条新闻对应的所有评论。改成这种写法之后,我们就可以将关联表数据的查询延迟,当我们需要去获取新闻所对应的评论时,再去调用News的getComments()方法,这时才会去查询关联数据。这种写法会比激进查询更加高效也更加合理。


原生查询

相信你已经体会到,LitePal在查询方面提供的API已经相当丰富了。但是,也许你总会遇到一些千奇百怪的需求,可能使用LitePal提供的查询API无法完成这些需求。没有关系,因为即使使用了LitePal,你仍然可以使用原生的查询方式(SQL语句)来去查询数据。DataSuppport类中还提供了一个findBySQL()方法,使用这个方法就能通过原生的SQL语句方式来查询数据了,如下所示:

Cursor cursor = DataSupport.findBySQL("select * from person where id > ?", "0");  

findBySQL()方法接收任意个字符串参数,其中第一个参数就是SQL语句,后面的参数都是用于替换SQL语句中的占位符的,用法非常简单。另外,findBySQL()方法返回的是一个Cursor对象,这和原生SQL语句的用法返回的结果也是相同的。

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/40153833

阅读全文
0 0
原创粉丝点击