ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PostgreSQL JSONB 操作符也能写进 DQL?DoctrineJsonFunctions 的 11 个 JSON 函数使用教程

PostgreSQL JSONB 操作符也能写进 DQL?DoctrineJsonFunctions 的 11 个 JSON 函数使用教程 PostgreSQL JSONB 操作符也能写进 DQLDoctrineJsonFunctions 的 11 个 JSON 函数使用教程【免费下载链接】DoctrineJsonFunctionsDoctrine DQL functions for SQL JSON data type项目地址: https://gitcode.com/gh_mirrors/do/DoctrineJsonFunctionsDoctrineJsonFunctions 是一套 Doctrine ORM 扩展专门把数据库原生的 JSON 函数包装成可在 DQL 中直接使用的函数。对于使用 PostgreSQL 的开发者来说它的亮点是、-、#这些平时只能在原生 SQL 里写的 JSONB 操作符现在也能出现在你的 Doctrine 查询里了。本文带你快速掌握 PostgreSQL 9.3 平台支持的 11 个 DQL JSON 函数 为什么需要把 JSONB 操作符写成 DQL 函数在原生 SQL 中PostgreSQL 的 JSON 操作非常灵活WHERE data {status: active} -- 包含判断 WHERE data - status active -- 按 key 取文本 WHERE data # {address,city} 杭州 -- 按路径取文本但 Doctrine DQL 不支持自定义操作符你在 DQL 里直接写会直接解析失败。DoctrineJsonFunctions 的解法很巧妙把每个操作符包装成一个具名 DQL 函数底层生成 SQL 时仍然输出原生的操作符。也就是说你写的是函数数据库执行的是最地道的操作符性能和索引使用如 GIN 索引配合与手写 SQL 完全一致。所有 PostgreSQL 相关实现都位于src/Query/AST/Functions/Postgresql/目录下。安装与注册三步让 JSONB 函数在 DQL 中可用第一步安装扩展包要求 PHP 8.1兼容 Doctrine ORM 2.19/3 与 DBAL 3.2/4composer require scienta/doctrine-json-functions第二步注册函数。在纯 Doctrine ORM 中把需要用到的函数注册为string_functionsuse Scienta\DoctrineJsonFunctions\Query\AST\Functions\Postgresql as PgFunctions; $config-addCustomStringFunction(PgFunctions\JsonbContains::FUNCTION_NAME, PgFunctions\JsonbContains::class); $config-addCustomStringFunction(PgFunctions\JsonGetText::FUNCTION_NAME, PgFunctions\JsonGetText::class);第三步如果是 Symfony 项目在doctrine.yaml中同样以string_functions形式声明即可doctrine: orm: dql: string_functions: JSONB_CONTAINS: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Postgresql\JsonbContains JSON_GET_TEXT: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Postgresql\JsonGetText每个函数类都暴露了FUNCTION_NAME常量与 DQL 中使用的关键字一一对应注册时照抄即可。11 个 PostgreSQL DQL JSON 函数速查表DQL 函数底层 SQL 等价写法用途JSONB_CONTAINSjsonb jsonb判断左文档是否包含右文档JSONB_IS_CONTAINEDjsonb jsonb判断左文档是否被右文档包含JSONB_EXISTSjsonb_exists(col, key)判断某个 key 是否存在JSONB_EXISTS_ALLjsonb_exists_all(col, {keys})判断所有 key 是否都存在JSONB_EXISTS_ANYjsonb_exists_any(col, {keys})判断是否任一 key 存在JSONB_INSERTjsonb_insert(...)向文档插入值不覆盖已有值JSON_GETjson - key取子对象/数组元素JSON_GET_TEXTjson - key取子对象并转为文本JSON_GET_PATHjson # {path}按路径数组取子对象JSON_GET_PATH_TEXTjson # {path}按路径数组取文本JSON_EXTRACT_PATHjson_extract_path(...)按路径提取子对象仅json列其中-、-、#、#四个操作符函数都继承自src/Query/AST/Functions/Postgresql/PostgresqlJsonOperatorFunctionNode.php只需声明一个OPERATOR常量就能复用全部解析逻辑这也是这个库加函数只需几行代码的架构精髓。常用场景实战场景一按条件筛选 JSONB 数据—— 查询所有包含{country: NL}的文档这是最能发挥 GIN 索引威力的一类查询$qb-select(c) -from(Customer::class, c) -andWhere(JSONB_CONTAINS(c.attributes, :attr) true) -setParameter(attr, {country: NL});注意返回值是布尔型DQL 里必须显式 true原因见下文避坑一节。场景二判断 key 是否存在—— 三个存在性函数覆盖不同需求。单个 key 用JSONB_EXISTS一组 key 全部存在用JSONB_EXISTS_ALL参数是{a,b}这样的数组字面量任一存在用JSONB_EXISTS_ANYSELECT JSONB_EXISTS_ALL(j.jsonCol, {a,b}) AS val FROM JsonbData j场景三按路径取值—— 一层路径用JSON_GET返回 JSON或JSON_GET_TEXT返回文本适合直接比较嵌套多层路径则用JSON_GET_PATH/JSON_GET_PATH_TEXT路径以数组字面量书写-andWhere(JSON_GET_TEXT(c.attributes, country) :country) -setParameter(country, NL)场景四安全更新——JSONB_INSERT只在 key 不存在时插入新值不会覆盖旧值适合同步默认配置而不破坏用户自定义字段。新手必知的 4 个坑 ⚠️布尔函数必须显式比较DQL 没有原生布尔函数类型JSONB_CONTAINS、JSONB_EXISTS、JSONB_EXISTS_ALL、JSONB_EXISTS_ANY、JSONB_IS_CONTAINED都要写成 true否则会触发解析错误。不支持操作符链式调用col-a-b这种写法在 DQL 里行不通请改用JSON_GET_PATHjson/jsonb列通用或JSON_EXTRACT_PATH仅json列。路径/键参数用单引号DQL 中 JSON 路径表达式必须是单引号字符串例如country、{a,b}。平台校验是即时报错所有函数在生成 SQL 时会校验当前平台确实是 PostgreSQL见PostgresqlJsonFunctionNode.php中的validatePlatform()用错数据库会第一时间抛出异常而不是生成一条坏 SQL。想深入了解源码11 个函数本体src/Query/AST/Functions/Postgresql/每个类平均不到 20 行参数解析与 SQL 生成的基类src/Query/AST/Functions/AbstractJsonFunctionNode.phpDBAL 3/4 版本兼容处理src/DBALCompatibility.php真实可用的 DQL 示例含集成测试tests/Integration/Functions/Postgresql/例如JsonbExistsAllTest.php演示了{a,b}多 key 判断的完整写法一句话总结写 DQL 的熟悉度得到原生 SQL 的 JSONB 能力——这就是 DoctrineJsonFunctions 给 PostgreSQL 项目带来的价值。【免费下载链接】DoctrineJsonFunctionsDoctrine DQL functions for SQL JSON data type项目地址: https://gitcode.com/gh_mirrors/do/DoctrineJsonFunctions创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表