当前位置: 首页 > news >正文

MyBatis的#和$符号详解(Java面试)

🤟致敬读者

  • 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉

📘博主相关

  • 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息

文章目录

  • Java面试中MyBatis的#和$符号详解
      • 1. **`#{}`(预编译占位符)**
      • 2. **`${}`(字符串直接替换)**
      • ⚠️ 关键对比总结
      • 🛡️ 使用建议
      • 🔍 面试回答要点


📃文章前言

  • 🔷文章均为学习工作中整理的笔记。
  • 🔶如有错误请指正,共同学习进步。

Java面试中MyBatis的#和$符号详解

在Java的MyBatis框架中,#{}${}是处理SQL参数的两种关键符号,它们在底层实现、安全性和使用场景上有显著区别:

1. #{}(预编译占位符)

  • 实现原理
    转换为JDBC的PreparedStatement参数占位符?,执行时通过setXxx()方法安全传参。
    SELECT * FROM user WHERE id = #{userId}
    → 实际执行:SELECT * FROM user WHERE id = ?   (参数值安全注入)
    
  • 安全性
    天然防止SQL注入(参数值不会作为SQL片段解析)。
  • 数据类型处理
    自动处理类型转换(如字符串添加引号、日期格式化)。
  • 适用场景
    所有数据值场景(WHERE条件值、INSERT/UPDATE值等)。

2. ${}(字符串直接替换)

  • 实现原理
    直接替换为参数值的字符串(不做预编译处理)。
    SELECT * FROM ${tableName} ORDER BY ${column}
    → 可能生成:SELECT * FROM orders ORDER BY create_time
    
  • 安全性
    有SQL注入风险(若参数值来自用户输入且未过滤)。
    ORDER BY ${input}   // 若input="1; DROP TABLE user--" 会导致灾难!
    
  • 数据类型处理
    需手动处理类型(如字符串需自行添加引号)。
  • 适用场景
    动态SQL关键字/结构(表名、列名、ORDER BY子句等无法预编译的位置)。

⚠️ 关键对比总结

特性#{}${}
底层机制预编译占位符 (?)字符串直接替换
SQL注入风险✅ 安全❌ 高风险(需严格校验参数)
处理数据类型自动添加引号/格式转换需手动处理(如字符串加' '
性能通常更优(数据库可缓存执行计划)每次生成新SQL
适用场景数据值(用户输入、条件值等)SQL结构(表名、列名、动态SQL片段)

🛡️ 使用建议

  1. 默认首选 #{}
    只要涉及数据值(特别是用户输入),强制使用#{}确保安全。

    <!-- 安全示例 -->
    <select id="findUser">SELECT * FROM user WHERE name = #{name} AND age > #{minAge} <!-- 正确做法 -->
    </select>
    
  2. 谨慎使用 ${}
    仅用于动态标识符(非数据),且必须做参数校验:

    <!-- 动态表名示例(需校验tableName合法性) -->
    <select id="selectFromTable">SELECT * FROM ${tableName} WHERE role = #{role}  <!-- 值仍用#{} -->
    </select>
    
  3. 禁止将用户输入直接用于 ${}
    若不可避免(如动态排序字段),应在代码层白名单校验

    // Java层校验示例
    public String safeOrderColumn(String input) {Set<String> validColumns = Set.of("name", "age", "create_time");return validColumns.contains(input) ? input : "id"; // 默认安全值
    }
    

🔍 面试回答要点

  • 根本区别
    #{}是参数化查询(安全),${}是字符串拼接(危险)。
  • 安全原则
    “数据值必用#{},动态结构慎用${},用户输入绝不用${}”。
  • 漏洞案例
    ${}未过滤导致"1; DELETE FROM user"会执行恶意SQL。
  • 动态表名解决方案
    ${}但需在业务层校验表名合法性(如映射预定义表名)。

📌 总结:MyBatis中SQL安全的核心在于——所有数据值必须通过#{}传递,仅在必要时(如动态表结构)对${}进行严格受控的使用。


📜文末寄语

  • 🟠关注我,获取更多内容。
  • 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
  • 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
  • 🔵​加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
  • 🟣点击下方名片获取更多内容🍭🍭🍭👇

相关文章:

  • AtCoder Beginner Contest 408
  • 循环冗余码校验CRC码 算法步骤+详细实例计算
  • 【C】十六进制(Hex)与ASCII
  • okhttp 实现长连接的完整方案
  • 降低显存,优化性能方案 MHA MQA GQA MLA MFA
  • 《高等数学》(同济大学·第7版)第四章第一节不定积分的概念与性质
  • CMake测试find_package()命令的相关原理
  • 商品中心—2.商品生命周期和状态的技术文档
  • [FX5U-PLC] 变频器的多段速变频调速控制系统
  • 可视化如何全方位赋能销售工作
  • Windows 文件路径与文件名限制
  • 大数据零基础学习day1之环境准备和大数据初步理解
  • CMOS图像传感器系列--(五)HDR之大小像素技术
  • 菲尔斯特传感器,超声波风速风向传感器助力绿色能源发展
  • 基于STM32F103C8T6单片机双极性SPWM逆变(软件篇)
  • 【单片机期末】汇编试卷
  • 51单片机读取PCF8563时钟芯片
  • IMX6ULL--EPIT 定时器理论
  • Docker加入用户组
  • Android Wi-Fi 连接失败日志分析
  • 网站建设类目/网站服务器地址查询
  • 做销售用什么网站/十大放黄不登录不收费
  • 建设大型网站设计公司/抖音seo是什么意思
  • 网站管理的内容包括/爱站网 关键词挖掘工具站
  • 哪个网站能把图片拼凑起来做gif的/做网站的步骤
  • 太原医疗网站建设/seo产品是什么意思