[NewLife.XCode]高级查询(化繁为简、分页提升性能)

NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。

整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。

开源地址:https://github.com/NewLifeX/X (求star, 754+)

 

扩展查询

前文《[NewLife.XCode]实体类详解》中有讲到扩展查询,XCode生成实体类代码时,在模型类有一个region叫“扩展查询”,一般是FindByAbc/FindAllByAbc的形式。

扩展查询以数据表索引为依据来生成:

  • 唯一索引(含主键)生成FindByAbc方法(如FindByName),返回单个对象;
  • 非唯一索引生成FindAllByAbc方法(如FindAllByClassID),返回对象列表(非null);

如上图,可知Entity实体基类内部,查询方法分为单对象查询的Find和对象列表的查询FindAll。

实际上,Find最终调用FindAll方法查一行。

 

Find/FindAll有多个重载,最主要的地方都是构造where查询条件。

下划线_是每个实体类都有的内嵌类,它包含了每一个字段的Field引用,借助运算符重载,可以很方便的构造查询条件,例如上面的_.Name == name最终会生成 where Name='Stone'

因为是内嵌类,在实体类内部使用的时候非常方便。但要是想要实体类外部使用,就麻烦很多了,需要带上实体类类名。

 

原则:XCode是充血模型,不管多么简单的查询,建议都封装Find/FindAll/Search等方法供外部使用。

 

高级表达式查询

 仅靠一两个字段的简单查询,肯定无法满足各种业务要求,我们需要更强大的查询支持,特别是根据不同条件拼接不同语句。

上面是两个非常典型的业务查询。

这里请出了条件表达式WhereExpression,实际上它只有两个功能,&表示And,|表示Or,根据表达式级别支持括号运算。

exp&=xxx 是最常用的写法,右边一般是各种Field表达式。

上面第一个例子,生成的查询语句可能是 select * from Student where classid=?classid and name like '%?key%'

为什么说“可能”?因为classid为0,或者key为空时,并不会参与拼接查询语句。

 

第二个例子稍微复杂一些,首先对key进行精确查询,找到了就返回,若是没找到,则开启模糊查询。 

这里遇到了等于、包含、区间等判断操作,后面会详解所有支持的操作。

 

如非必要,建议保留select * 的查询方式,而不是指定列。 

码农法则:数据库压力小于100qps时不要考虑指明select列来优化,大多数系统活不到需要优化的明天!

 

高级分页 

两个例子都出现了一个PageParameter参数page,这是分页参数,包含分页查询以及排序所需要的数据。

PageIndex和PageSize指定页序号和每页大小,这是内部建立分页查询的核心依据;

Sort 指定排序字段,Desc 指定是否降序(默认升序);

RetrieveTotalCount 指定是否或者总记录数,若为true,则在查询记录集之前,先查询满足条件的总行数TotalCount,用于分页PageCount。此时等于执行两次数据库查询;

RetrieveState 指定是否获取统计 State,若为true,则在查询记录集之后,执行聚合查询,对数字型字段使用Sum聚合。此时最多可能执行3次数据库查询;

 

XCode要求数据查询必须考虑分页,没有分页的系统一般死在100万行以内。

 

Field扩展

内嵌类_引用的字段是Field,它继承自FieldItem。

Field/FieldItem全部功能:

  • Equal 等于,操作符==
  • NotEqual 不等于,操作符!=
  • 大于操作符>,大于等于>=
  • 小于操作符<,小于等于<=
  • StartsWith 字符串开始,like '{0}%'。(支持索引)
  • EndsWith 字符串结束,like '%{0}'
  • Contains 字符串包含,like '%{0}%'
  • In 集合包含,支持列表集合、字符串子查询和SelectBuilder子查询,集合只有一个元素时转为相等操作
  • NotIn 集合不包含,支持列表集合、字符串子查询和SelectBuilder子查询,集合只有一个元素时转为不相等操作
  • IsNull 是否空
  • NotIsNull 不是空
  • IsNullOrEmpty 字符串空或零长度
  • NotIsNullOrEmpty 字符串非空非零长度
  • IsTrue 是否True或者False/Null,参数决定两组之一
  • IsFalse 是否False或者True/Null,参数决定两组之一
  • Between 时间区间,大于等于开始,小于结束,如果开始结束都只有日期而没有时分秒,则结束加一天,如(2019-04-17,  2019-04-17)查 time>='2019-04-17' and time<2019-04-18'

排序字句/分组聚合

  • Asc,升序
  • Desc,降序。order by name desc
  • GroupBy,分组。group by name
  • As,聚合别名
  • Count,计数
  • Sum,求和
  • Min,最小
  • Max,最大

 

查询的本质

查询的本质是五参数版FindAll(where, order, selects, start, maxnums),其它查询方式都由它转化而来!

Entity实体基类封装了各种常用的查询方法:

对于单表查询的XCode来说,五参数版FindAll很容易得到 select [selects] from [table] where [where] order by [order] limit [start], [maxnums] 语句,根据这个理念,FindAll可以支持任意复杂查询!

最终查询语句,由SelectBuilder类承载。 

 

系列教程

NewLife.XCode教程系列[2019版]

  1. 增删改查入门。快速展现用法,代码配置连接字符串
  2. 数据模型文件。建立表格字段和索引,名字以及数据类型规范,推荐字段(时间,用户,IP)
  3. 实体类详解。数据类业务类,泛型基类,接口
  4. 功能设置。连接字符串,调试开关,SQL日志,慢日志,参数化,执行超时。代码与配置文件设置,连接字符串局部设置
  5. 反向工程。自动建立数据库数据表
  6. 数据初始化。InitData写入初始化数据
  7. 高级增删改。重载拦截,自增字段,Valid验证,实体模型(时间,用户,IP)
  8. 脏数据。如何产生,怎么利用
  9. 增量累加。高并发统计
  10. 事务处理。单表和多表,不同连接,多种写法
  11. 扩展属性。多表关联,Map映射
  12. 高级查询。复杂条件,分页,自定义扩展FieldItem,查总记录数,查汇总统计
  13. 数据层缓存。Sql缓存,更新机制
  14. 实体缓存。全表整理缓存,更新机制
  15. 对象缓存。字典缓存,适用用户等数据较多场景。
  16. 百亿级性能。字段精炼,索引完备,合理查询,充分利用缓存
  17. 实体工厂。元数据,通用处理程序
  18. 角色权限。Membership
  19. 导入导出。Xml,Json,二进制,网络或文件
  20. 分表分库。常见拆分逻辑
  21. 高级统计。聚合统计,分组统计
  22. 批量写入。批量插入,批量Upsert,异步保存
  23. 实体队列。写入级缓存,提升性能。
  24. 备份同步。备份数据,恢复数据,同步数据
  25. 数据服务。提供RPC接口服务,远程执行查询,例如SQLite网络版
  26. 大数据分析。ETL抽取,调度计算处理,结果持久化

 

posted @ 2019-04-17 22:36 大石头 阅读(...) 评论(...) 编辑 收藏