Isar数据库查询全指南:从基础到高级技巧
前言
Isar作为一款高性能的本地数据库解决方案,其查询功能是开发者最常使用的核心特性之一。本文将全面介绍Isar中的查询机制,帮助开发者掌握从基础查询到高级优化的各种技巧。
基础查询概念
查询是数据库操作中最常见的需求,它允许我们根据特定条件查找记录。Isar查询直接在数据库层面执行,而非在Dart层处理,因此具有极高的性能表现。
查询示例场景
- 查找所有标记为星标的联系人
- 查找联系人中不重复的名字
- 删除所有没有姓氏的联系人
两种过滤方式
Isar提供了两种主要的过滤方式:Filters和Where子句。
Filters过滤器
Filters是最基础且易于理解的查询方式。它会针对集合中的每个对象评估表达式,如果结果为true,则将该对象包含在结果中。
基本查询条件
根据字段类型不同,可用的条件操作也不同:
| 条件 | 描述 | |---------------------|-----------------------------| | .equalTo(value)
| 匹配等于指定值的记录 | | .between(lower, upper)
| 匹配在指定范围内的记录 | | .greaterThan(bound)
| 匹配大于指定值的记录 | | .lessThan(bound)
| 匹配小于指定值的记录 | | .isNull()
| 匹配值为null的记录 | | .isNotNull()
| 匹配值不为null的记录 |
逻辑运算符
可以使用以下逻辑运算符组合条件:
.and()
: 与运算.or()
: 或运算.xor()
: 异或运算.not()
: 非运算.group()
: 条件分组
字符串查询
字符串字段支持额外的查询条件:
.startsWith(value)
: 以指定值开头.contains(value)
: 包含指定值.endsWith(value)
: 以指定值结尾.matches(wildcard)
: 匹配通配符模式
Where子句
Where子句是更强大的查询工具,它利用schema中定义的索引来检查查询条件,性能远高于过滤器。
索引的优势
- 查询索引比逐个过滤记录快得多
- 自动提供"免费"的排序功能
- 支持高效的distinct操作
使用建议
- 尽量先用Where子句缩小结果集范围
- 剩余过滤条件再用Filters处理
- 只能使用OR逻辑组合多个Where子句
查询修饰符
Isar提供了强大的条件查询构建工具:
.optional()
: 条件性扩展查询.anyOf()
: 对列表中的每个值扩展查询(OR逻辑).allOf()
: 对列表中的每个值扩展查询(AND逻辑)
集合查询
可以对列表类型的字段进行查询:
.isEmpty()
: 匹配空列表.lengthGreaterThan()
: 匹配长度大于指定值的列表.elementEqualTo()
: 匹配包含特定元素的列表
嵌入式对象查询
嵌入式对象可以使用与顶级对象相同的条件进行高效查询:
final germanCars = await isar.cars.filter()
.brand((q) => q
.nameEqualTo('BMW')
.and()
.countryEqualTo('Germany')
).findAll();
链接查询
可以通过链接对象或链接数量进行过滤:
final result = await isar.students.filter()
.teachers((q) {
return q.subjectEqualTo('Math')
.or()
.subjectEqualTo('English');
}).findAll();
注意:链接查询可能较昂贵,建议优先考虑嵌入式对象。
排序操作
可以使用以下方法定义结果排序:
.sortBy()
: 升序排序.sortByDesc()
: 降序排序.thenBy()
: 次级升序排序.thenByDesc()
: 次级降序排序
Where子句排序技巧
如果使用单个Where子句,结果已经按索引排序,这是极大的性能优势。
唯一值查询
使用distinct操作获取唯一值记录:
final shoes = await isar.shoes.filter()
.distinctByModel()
.findAll();
分页查询
对于列表视图,限制结果数量是个好主意:
final firstTenShoes = await isar.shoes.where()
.offset(20)
.limit(10)
.findAll();
查询执行顺序
Isar查询总是按以下顺序执行:
- 遍历索引应用Where子句
- 应用Filters过滤
- 排序结果
- 应用distinct操作
- 应用offset和limit
- 返回结果
查询操作类型
除了.findAll()
,还有其他有用的操作:
| 操作 | 描述 | |----------------|------------------------| | .findFirst()
| 只检索第一个匹配对象 | | .findAll()
| 检索所有匹配对象 |
性能优化建议
- 合理设计和使用索引
- 先用Where子句缩小结果集
- 避免不必要的对象实例化
- 对大数据集使用分页
- 考虑使用嵌入式对象替代链接
通过掌握这些查询技巧,您可以充分发挥Isar数据库的性能优势,构建高效的应用程序。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考