如何在Laminas-Db的WHERE子句中使用JSON_EXTRACT?
在Laminas-Db的TableGateway中使用JSON_EXTRACT作为WHERE条件
你的MySQL表结构如下,其中comments字段采用JSON类型存储数据:
| id | author_id | date_inserted | comments |
|---|---|---|---|
| 1 | 32 | 2022-04-01 | {"id": "343","some":"data"} |
| 2 | 15 | 2022-02-15 | {"id": "24","some":"data"} |
| 3 | 24 | 2022-05-22 | {"id": "995","some":"data"} |
要在TableGateway的update方法中用JSON_EXTRACT作为WHERE条件,不能直接像你写的那样把函数调用放在数组里——因为TableGateway会把数组的键当作字段名解析,导致语法错误。正确的做法是用Laminas\Db\Sql\Expression来包装SQL表达式,以下是具体实现方式:
方法一:直接在WHERE参数中使用Expression
use Laminas\Db\Sql\Expression; // 构造包含JSON_EXTRACT的WHERE条件 $where = [ new Expression('JSON_EXTRACT(comments, ?) = ?', ['$.id', 24]) ]; // 执行更新操作 $this->tableGateway->update($data, $where);
这种方式通过Expression对象告诉Laminas-Db这是一段原生SQL表达式,同时用占位符?传递参数,能有效避免SQL注入问题。
方法二:使用Sql组件构建更新语句
如果需要更复杂的查询逻辑,可以借助Sql组件来构建:
use Laminas\Db\Sql\Sql; use Laminas\Db\Sql\Where; $sql = new Sql($this->tableGateway->getAdapter()); $update = $sql->update(); $update->set($data) ->where(function (Where $where) { // 在闭包中添加表达式条件 $where->expression('JSON_EXTRACT(comments, ?) = ?', ['$.id', 24]); }); // 执行语句 $statement = $sql->prepareStatementForSqlObject($update); $statement->execute();
简化写法(MySQL 5.7+支持)
MySQL 5.7及以上版本支持->语法简化JSON字段的提取,你也可以用这种写法:
$where = [ new Expression('comments->? = ?', ['$.id', 24]) ]; $this->tableGateway->update($data, $where);
内容的提问来源于stack exchange,提问作者John Crest
相关产品推荐
相关产品推荐

