查询构造器

简介

Hyperf 的数据库查询构造器为创建和运行数据库查询提供了一个方便的接口。它可用于执行应用程序中大部分数据库操作,且可在所有支持的数据库系统上运行。

Hyperf 的查询构造器使用 PDO 参数绑定来保护您的应用程序免受 SQL 注入攻击。因此没有必要清理作为绑定传递的字符串。

这里只提供一部分常用的教程,具体教程可以到 Laravel 官网查看。Laravel Query Builder

获取结果

Db::select() 方法会返回一个 array,而 get 方法会返回 HyperfUtilsCollection。其中元素是 stdClass,所以可以通过以下代码返回各个元素的数据

将结果转为数组格式

在某些场景下,您可能会希望查询出来的结果内采用 数组(Array) 而不是 stdClass 对象结构时,而 Eloquent 又去除了通过配置的形式配置默认的 FetchMode,那么此时可以通过监听器来监听 HyperfDatabaseEventsStatementPrepared 事件来变更该配置:

获取一行的值

如果想获取一行的值, 则可以使用 first 方法

获取单个值

如果想获取单个值, 则可以使用 value 方法

获取一列的值

如果你想获取包含单列值的集合,则可以使用 pluck 方法。在下面的例子中,我们将获取角色表中标题的集合:

你还可以在返回的集合中指定字段的自定义键值:

分块结果

如果你需要处理上千条数据库记录,你可以考虑使用 chunk 方法。该方法一次获取结果集的一小块,并将其传递给 闭包 函数进行处理。该方法在 Command 编写数千条处理数据的时候非常有用。例如,我们可以将全部 user 表数据切割成一次处理 100 条记录的一小块:

你可以通过在 闭包 中返回 false 来终止继续获取分块结果:

如果要在分块结果时更新数据库记录,则块结果可能会和预计的返回结果不一致。 因此,在分块更新记录时,最好使用 chunkById 方法。 此方法将根据记录的主键自动对结果进行分页:

在块的回调里面更新或删除记录时,对主键或外键的任何更改都可能影响块查询。 这可能会导致记录没有包含在分块结果中。

聚合查询

框架还提供了聚合类方法,例如 count, max, min, avg, sum。

判断记录是否存在

除了通过 count 方法可以确定查询条件的结果是否存在之外,还可以使用 exists 和 doesntExist 方法:

查询

指定一个 Select 语句

当然你可能并不总是希望从数据库表中获取所有列。使用 select 方法,你可以自定义一个 select 查询语句来查询指定的字段:

distinct 方法会强制让查询返回的结果不重复:

如果你已经有了一个查询构造器实例,并且希望在现有的查询语句中加入一个字段,那么你可以使用 addSelect 方法:

原始表达式

有时你需要在查询中使用原始表达式,例如实现 COUNT(0) AS count,这就需要用到 raw 方法。

强制索引

数据库出现的慢查问题, 90% 以上是索引不对, 其中有部分查询是因为数据库服务器的 查询优化器 没有使用最佳索引, 这时候就需要使用强制强制索引:

原生方法

可以使用以下方法代替 Db::raw,将原生表达式插入查询的各个部分。

selectRaw 方法可以代替 select(Db::raw(...))。该方法的第二个参数是可选项,值是一个绑定参数的数组:

whereRaw 和 orWhereRaw 方法将原生的 where 注入到你的查询中。这两个方法的第二个参数还是可选项,值还是绑定参数的数组:

havingRaw 和 orHavingRaw 方法可以用于将原生字符串设置为 having 语句的值:

orderByRaw 方法可用于将原生字符串设置为 order by 子句的值:

表连接

Inner Join Clause

查询构造器也可以编写 join 方法。若要执行基本的「内链接」,你可以在查询构造器实例上使用 join 方法。传递给 join 方法的第一个参数是你需要连接的表的名称,而其他参数则使用指定连接的字段约束。你还可以在单个查询中连接多个数据表:

Left Join

如果你想使用「左连接」或者「右连接」代替「内连接」,可以使用 leftJoin 或者 rightJoin 方法。这两个方法与 join 方法用法相同:

Cross Join 语句

使用 crossJoin 方法和你想要连接的表名做「交叉连接」。交叉连接在第一个表和被连接的表之间会生成笛卡尔积:

高级 Join 语句

你可以指定更高级的 join 语句。比如传递一个 闭包 作为 join 方法的第二个参数。此 闭包 接收一个 JoinClause 对象,从而指定 join 语句中指定的约束:

如果你想要在连接上使用「where」风格的语句,你可以在连接上使用 where 和 orWhere 方法。这些方法会将列和值进行比较,而不是列和列进行比较:

子连接查询

你可以使用 joinSub,leftJoinSub 和 rightJoinSub 方法关联一个查询作为子查询。他们每一种方法都会接收三个参数:子查询,表别名和定义关联字段的闭包:

联合查询

查询构造器还提供了将两个查询 「联合」 的快捷方式。比如,你可以先创建一个查询,然后使用 union 方法将其和第二个查询进行联合:

Where 语句

简单的 Where 语句

在构造 where 查询实例的中,你可以使用 where 方法。调用 where 最基本的方式是需要传递三个参数:第一个参数是列名,第二个参数是任意一个数据库系统支持的运算符,第三个是该列要比较的值。

例如,下面是一个要验证 gender 字段的值等于 1 的查询:

为了方便,如果你只是简单比较列值和给定数值是否相等,可以将数值直接作为 where 方法的第二个参数:

当然,你也可以使用其他的运算符来编写 where 子句:

你还可以传递条件数组到 where 函数中:

Or 语句

你可以一起链式调用 where 约束,也可以在查询中添加 or 字句。 orWhere 方法和 where 方法接收的参数一样:

其他 Where 语句

whereBetween

whereBetween 方法验证字段值是否在给定的两个值之间:

whereNotBetween

whereNotBetween 方法验证字段值是否在给定的两个值之外:

whereIn / whereNotIn

whereIn 方法验证字段的值必须存在指定的数组里:

whereNotIn 方法验证字段的值必须不存在于指定的数组里:

参数分组

有时候你需要创建更高级的 where 子句,例如「where exists」或者嵌套的参数分组。查询构造器也能够处理这些。下面,让我们看一个在括号中进行分组约束的例子:

你可以看到,通过一个 Closure 写入 where 方法构建一个查询构造器 来约束一个分组。这个 Closure 接收一个查询实例,你可以使用这个实例来设置应该包含的约束。上面的例子将生成以下 SQL:

你应该用 orWhere 调用这个分组,以避免应用全局作用出现意外.

Where Exists 语句

whereExists 方法允许你使用 where exists SQL 语句。 whereExists 方法接收一个 Closure 参数,该 whereExists 方法接受一个 Closure 参数,该闭包获取一个查询构建器实例从而允许你定义放置在 exists 字句中查询:

上述查询将产生如下的 SQL 语句:

JSON Where 语句

Hyperf 也支持查询 JSON 类型的字段(仅在对 JSON 类型支持的数据库上)。

你也可以使用 whereJsonContains 来查询 JSON 数组:

你可以使用 whereJsonLength 来查询 JSON 数组的长度:

Ordering, Grouping, Limit, & Offset

orderBy

orderBy 方法允许你通过给定字段对结果集进行排序。 orderBy 的第一个参数应该是你希望排序的字段,第二个参数控制排序的方向,可以是 asc 或 desc

latest / oldest

latest 和 oldest 方法可以使你轻松地通过日期排序。它默认使用 created_at 列作为排序依据。当然,你也可以传递自定义的列名:

inRandomOrder

inRandomOrder 方法被用来将结果随机排序。例如,你可以使用此方法随机找到一个用户。

groupBy / having

groupBy 和 having 方法可以将结果分组。 having 方法的使用与 where 方法十分相似:

你可以向 groupBy 方法传递多个参数:

对于更高级的 having 语法,参见 havingRaw 方法。

skip / take

要限制结果的返回数量,或跳过指定数量的结果,你可以使用 skip 和 take 方法:

或者你也可以使用 limit 和 offset 方法:

条件语句

有时候你可能想要子句只适用于某个情况为真是才执行查询。例如你可能只想给定值在请求中存在的情况下才应用 where 语句。 你可以通过使用 when 方法:

when 方法只有在第一个参数为 true 的时候才执行给的的闭包。如果第一个参数为 false ,那么这个闭包将不会被执行

你可以传递另一个闭包作为 when 方法的第三个参数。 该闭包会在第一个参数为 false 的情况下执行。为了说明如何使用这个特性,我们来配置一个查询的默认排序:

插入

查询构造器还提供了 insert 方法用于插入记录到数据库中。 insert 方法接收数组形式的字段名和字段值进行插入操作:

你甚至可以将数组传递给 insert 方法,将多个记录插入到表中

自增 ID

如果数据表有自增 ID ,使用 insertGetId 方法来插入记录并返回 ID 值

更新

当然, 除了插入记录到数据库中,查询构造器也可以通过 update 方法更新已有的记录。 update 方法和 insert 方法一样,接受包含要更新的字段及值的数组。你可以通过 where 子句对 update 查询进行约束:

更新或者新增

有时您可能希望更新数据库中的现有记录,或者如果不存在匹配记录则创建它。 在这种情况下,可以使用 updateOrInsert 方法。 updateOrInsert 方法接受两个参数:一个用于查找记录的条件数组,以及一个包含要更改记录的键值对数组。

updateOrInsert 方法将首先尝试使用第一个参数的键和值对来查找匹配的数据库记录。 如果记录存在,则使用第二个参数中的值去更新记录。 如果找不到记录,将插入一个新记录,更新的数据是两个数组的集合:

更新 JSON 字段

更新 JSON 字段时,你可以使用 -> 语法访问 JSON 对象中相应的值,此操作只能支持 MySQL 5.7+:

自增与自减

查询构造器还为给定字段的递增或递减提供了方便的方法。此方法提供了一个比手动编写 update 语句更具表达力且更精练的接口。

这两种方法都至少接收一个参数:需要修改的列。第二个参数是可选的,用于控制列递增或递减的量:

你也可以在操作过程中指定要更新的字段:

删除

查询构造器也可以使用 delete 方法从表中删除记录。 在使用 delete 前,可以添加 where 子句来约束 delete 语法:

如果你需要清空表,你可以使用 truncate 方法,它将删除所有行,并重置自增 ID 为零:

悲观锁

查询构造器也包含一些可以帮助你在 select 语法上实现「悲观锁定」的函数。若想在查询中实现一个「共享锁」, 你可以使用 sharedLock 方法。 共享锁可防止选中的数据列被篡改,直到事务被提交为止

或者,你可以使用 lockForUpdate 方法。使用「update」锁可避免行被其它共享锁修改或选取:

hyper运算符_查询构造器相关推荐

  1. MySQL—运算符详解(算术、比较、逻辑、范围运算符与集合运算符 模糊查询 NULL值运算与null值判断 位运算符)

    MySQL--运算符详解 知识纲要 算术运算符 比较运算符 逻辑运算符 范围运算符与集合运算符 模糊查询 NULL值运算与null值判断 位运算符 1.算术运算符 加 减 乘 除 取余 div 也表示 ...

  2. 【JEECG技术文档】JEECG高级查询构造器使用说明

    功能介绍   高级查询构造器支持主子表联合查询,查询出更精确的数据. 要使用高级查询构造器需要完成以下步骤: 1. 在高级查询管理配置主子表信息. 2. 配置完后在JSP页面DataGrid标签上添加 ...

  3. sql查询时间大于某一时间_查询时间从24分钟到2秒钟:记一次神奇的SQL优化

      作者 | VWO译者 | 无明编辑 | VincentAI 前线导读:去年十二月份,VWO 平台支持团队发布了一份缺陷报告.这份报告很有意思,其中有一个来自某家企业用户的分析查询,它的运行速度非常 ...

  4. MySQL带关系运算符的查询

    带关系运算符的查询 SELECT语句中,最常用的是使用WHERE子句,指定查询条件对数据进行过滤. SELECT 字段名1,字段名2,-- FROM 表名 WHERE 条件表达式 参数说明 条件表达式 ...

  5. 写一个“特殊”的查询构造器 - (四、条件查询:复杂条件)

    复杂的条件 在 SQL 的条件查询中,不只有 where.or where 这些基本的子句,还有 where in.where exists.where between 等复杂一些的子句.而且即使是 ...

  6. 【laravel5.4】查询构造器对象与模型instance的互相换换

    1.查询构造器一般情况下返回对象,但是无法直接使用model类的一些方法,如toJson.toArray等 DB::table 结果转换成 model 类实例[collect 实例] public f ...

  7. 数据库构造器之查询构造器构建

    近来使用笔者研发的框架中,有一处功能颇为棘手. 由于框架内部监控功能中,需存储当前操作用户主键功能. 然,获取用户主键的模块中,需根据"loginToken"获取"账号主 ...

  8. Laravel Database——查询构造器与语法编译器源码分析 (上)

    前言 在前两个文章中,我们分析了数据库的连接启动与数据库底层 CRUD 的原理,底层数据库服务支持原生 sql 的运行.本文以 mysql 为例,向大家讲述支持 Fluent 的查询构造器 query ...

  9. laravel数据库: 查询构造器

    数据库: 查询构造器 获取结果 从表中检索所有行 get use Illuminate\Support\Facades\DB;$users = DB::table('users')->get() ...

  10. Mybatis-plus条件查询构造器

    Mybatis-plus条件查询构造器 一.wapper介绍 二.AbstractWrapper 1.ge.gt.le.lt.isNull.isNotNull 2.eq.ne 3.between.no ...

最新文章

  1. PyTorch 笔记(20)— torchvision 的 datasets、transforms 数据预览和加载、模型搭建(torch.nn.Conv2d/MaxPool2d/Dropout)
  2. 微服务网关从零搭建——(七)更改存储方式为oracle
  3. html显示三维模型restful,返回带有Flask Restful的呈现模板,在浏览器中显示HTML
  4. 播放视频android学习笔记---44_在线视频播放器,网络视频解析器,SurfaceView 控件使用方法...
  5. python一般用来开发什么-python主要用来做什么?Python开发简单吗?
  6. C语言常用宏定义(#define)使用方法
  7. nodejs+express整合kindEditor实现图片上传
  8. [SDOI 2010]外星千足虫
  9. 信息学奥赛一本通 2005:【20CSPJ普及组】直播获奖 | 洛谷 P7072 [CSP-J2020] 直播获奖
  10. Python机器学习:SVM005SVM使用多项式特征
  11. 《矩阵分析》Ⅳ——三对角矩阵的追赶法matlab实现
  12. 高质量编程之编译警告级别
  13. 税务Ukey如何进行批量开票
  14. 大华linux密码,大华wifi摄像头的初始化和读取视频流
  15. Java基础 实验二:类和对象
  16. python绘制折线图怎么样填充空白颜色_两条折线图之间填充颜色
  17. 电脑硬件升级完全解决方案2
  18. 核心网upf作用_5G toB,核心网如何演进?
  19. STP生成树原理及选举规则举例
  20. mysql中cube是什么意思中文,什么是EC-CUBE

热门文章

  1. 网站建设解决了传统的销售模式
  2. 轻松搭建Windows8云平台开发环境
  3. redis scan命令详解
  4. 把 mysql sql_mode 设置为严格模式的方法
  5. matlab 的 legend 用法
  6. 20.20 告警系统主脚本;20.21 告警系统配置文件;20.22 告警系统监控项目
  7. 《一胜九败》读书笔记
  8. 成熟的云管理是什么样的?
  9. DDoSCoin:加密货币奖励用户参与 DDoS 攻击
  10. 全局变量不能放在头文件其中