MyBatis编写Neo4j查询时$与#的注意事项

在 MyBatis 中编写 Neo4j 查询时,#{} 和 ${} 的主要区别在于参数替换的方式,这与 MyBatis 操作传统关系型数据库时的规则类似,但在 Neo4j 的 Cypher 查询中有一些特殊注意事项。

必须使用 ${} 而不能用 #{} 的情况:

  1. 动态标识符(节点标签、关系类型、属性名):

    • 当需要动态指定节点标签、关系类型或属性名时,必须使用 ${},因为这些位置 Cypher 语法不接受参数化。

    • 例如:

      xml 复制代码
      MATCH (n:${label}) WHERE n.${property} = #{value} RETURN n

      这里 label 和 property 必须用 ${},而 value 可以用 #{}。

  2. Cypher 关键字或子句动态拼接:

    • 如果需要动态拼接 Cypher 的关键字部分(如 ORDER BY、WHERE 条件等),必须使用 ${}。

    • 例如:

      xml 复制代码
      MATCH (n:Person) ${whereClause} RETURN n
  3. 动态索引或约束名称:

    • 创建或使用索引/约束时,名称需要用 ${}。
  4. Cypher 函数或特殊语法:

    • 如果参数需要作为 Cypher 函数名或特殊语法的一部分。

应该使用 #{} 的情况:

  • 对于普通的属性值、查询参数等,应该始终优先使用 #{},因为:
    • 它会被预编译为参数化查询,防止 Cypher 注入

    • 有类型安全处理

    • 例如:

      xml 复制代码
      MATCH (n:Person) WHERE n.name = #{name} RETURN n

安全注意事项:

  1. 永远不要用 ${} 直接接收用户输入,这会导致 Cypher 注入风险
  2. 如果必须使用 ${},应该:
    • 仅在动态 SQL 的必要部分使用
    • 确保值来自可信来源(如系统常量、枚举值等)
    • 考虑在应用层做白名单校验

示例对比:

xml 复制代码
<!-- 安全的方式 -->
<select id="findByLabelAndProperty">
    MATCH (n:${label}) WHERE n.${property} = #{value} RETURN n
</select>

<!-- 危险的方式(不要这样用) -->
<select id="findByLabelUnsafe">
    MATCH (n:${userInput}) RETURN n  <!-- 可能被注入 -->
</select>

总结:在 Neo4j 查询中,只有当需要动态改变 Cypher 查询的结构部分(标签、属性名、关系类型等)时才必须用 ${},其他所有值都应该用 #{}。

相关推荐
geovindu27 分钟前
rust: Chain of Responsibility Pattern (续)
开发语言·后端·设计模式·rust·责任链模式·行为模式
郝学胜-神的一滴43 分钟前
Web安全入门:读懂Web世界里的攻防
前端·网络·后端·安全·web安全·hibernate
天若有情67343 分钟前
从零搭建校园二手交易系统:Vue2 + SpringBoot 4.x 全栈实战
java·spring boot·后端
Lost of 程序猿1 小时前
责任链模式实战:审批流里“层层把关“的艺术
后端·设计模式·asp.net·责任链模式
知守观1 小时前
Maven SNAPSHOT 更新排查:-U 无效、clean 无用,问题在 _remote.repositories(附完整链路)
java·后端·maven
IT_陈寒1 小时前
一文搞懂SpringBoot的核心概念
前端·人工智能·后端
Mikko72 小时前
fastjson 1.2.84 能在 JDK 7 上跑吗?实测:编译能过,一启动就 UnsupportedClassVersionError
java·后端·jdk·fastjson·安全漏洞
高频因子挖掘机2 小时前
股票 API 返回 HTTP 429 怎么办?Python 量化系统的限流排查与重试设计
后端·github·api
mldong2 小时前
为了 token 自由,我把 jeeflow 工作流引擎用 MoonBit 写了一遍
后端·架构