MyBatis增删改查:静态与动态SQL语句拼接及SQL注入问题解析
MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作。本文将深入探讨 MyBatis 中的增删改查操作,重点讲解静态与动态 SQL 语句的拼接,并分析 SQL 注入问题及其防范措施。
1. MyBatis 基础配置
在开始之前,我们需要配置 MyBatis 的基本环境。以下是一个简单的 pom.xml 配置文件,包含了 MyBatis 的核心依赖和 MySQL 驱动依赖:
<dependencies><!-- MyBatis 核心包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!-- MySQL 驱动包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!-- 单元测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version></dependency><!-- 日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>
</dependencies>
2. 静态 SQL 语句
静态 SQL 语句是指在编写 SQL 时,SQL 语句的结构和内容是固定的,不会根据条件的变化而变化。以下是一个简单的静态 SQL 查询示例:
<!--id:方法名--><!--resultType:定义数据的返回-->
<!-- <select id="findAll" resultType="com.qcby.entity.User">-->
<!-- select *from user;-->
<!-- </select>--><!-- <select id="findById" resultType="com.qcby.entity.User" parameterType="java.lang.Integer">-->
<!-- select * from user where id=#{id}-->
<!-- </select>--><!-- <select id="selectByUserName" resultType="com.qcby.entity.User" parameterType="java.lang.String">-->
<!-- select *from user where username=#{username}-->
<!-- </select>--><!-- <insert id="insert" parameterType="com.qcby.entity.User">-->
<!-- insert into user (username,birthday,sex,address) value (#{username},#{birthday},#{sex},#{address});-->
<!-- </insert>--><!-- <update id="update" parameterType="com.qcby.entity.User">-->
<!-- update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}-->
<!-- where id=#{id}-->
<!-- </update>--><!-- <delete id="delete" parameterType="java.lang.Integer">-->
<!-- delete from user where id=#{id}-->
<!-- </delete>-->
<!-- <select id="likeByName" resultType="com.qcby.entity.User" parameterType="java.lang.String">-->
<!-- select * from user where username like '%${value}%';-->
<!-- </select>-->
<!-- <select id="likeByName1" resultType="com.qcby.entity.User" parameterType="java.lang.String">-->
<!-- select * from user where username like #{username};-->
<!-- </select>-->
在这个例子中,findAll 方法会返回 user 表中的所有记录。静态 SQL 语句适用于简单的查询场景,但在复杂的业务逻辑中,静态 SQL 往往无法满足需求。
3. 动态 SQL 语句
动态 SQL 是 MyBatis 的强大特性之一,它允许我们根据不同的条件动态生成 SQL 语句。MyBatis 提供了多种标签来实现动态 SQL,如 <if>、<choose>、<when>、<otherwise>、<trim>、<where>、<set> 和 <foreach>。
3.1 <if> 标签
<if> 标签用于根据条件判断是否包含某段 SQL 语句。以下是一个使用 <if> 标签的动态 SQL 示例:
<!--动态sql:能够在不同的条件下拼接出不同的sql语句--><!--where 标签的功能:能够去掉where 后边的 and 或 or--><select id="selectUser" parameterType="com.qcby.entity.User" resultType="com.qcby.entity.User">select * from user<where><if test="username!=null and username!=''">username=#{username}</if><if test="birthday!=null">and birthday=#{birthday}</if><if test="sex!=null and sex!=''">and sex=#{sex}</if><if test="address!=null and address!=''">and address=#{address}</if></where></select>
在这个例子中,selectUser 方法会根据传入的 User 对象的 username 和 sex 属性动态生成 SQL 语句。如果 username 或 sex 为空,则不会包含对应的条件。
3.2 <choose>、<when> 和 <otherwise> 标签
<choose> 标签类似于 Java 中的 switch 语句,它可以根据不同的条件选择不同的 SQL 片段。以下是一个使用 <choose> 标签的示例:
<select id="selectUserByChoose" resultType="com.qcby.entity.User" parameterType="com.qcby.entity.User">SELECT * FROM user<where><choose><when test="username != null and username != ''">username = #{username}</when><when test="sex != null and sex != ''">sex = #{sex}</when><otherwise>id = #{id}</otherwise></choose></where>
</select>
在这个例子中,selectUserByChoose 方法会根据 username、sex 和 id 的不同值动态生成 SQL 语句。
3.3 <foreach> 标签
<foreach> 标签用于遍历集合或数组,并生成相应的 SQL 语句。以下是一个使用 <foreach> 标签的批量删除示例:
<!--foreach循环--><!--批量删除--><!-- 批量删除的sql语句:delete from user where id in (6,7,8); --><delete id="deleteMoreByArray" >delete from user where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach></delete><!-- collection:当前要循环的数组或者集合 --><!-- item: 我们指定要循环的数组的每一个元素 --><!-- separator:每一个元素应该用什么来做分割 --><!-- open:当前循环是以什么开始 --><!-- close:当前循环是以什么结束 --><!--批量添加--><!--insert into user(username,birthday,sex,address) values (#{user.username},#{user.birthday},#{user.sex},#{user.address}), (#{user.username},#{user.birthday},#{user.sex},#{user.address}), (#{user.username},#{user.birthday},#{user.sex},#{user.address}), (#{user.username},#{user.birthday},#{user.sex},#{user.address}) --><update id="insertMoreByList" parameterType="com.qcby.entity.User">insert into user(username,birthday,sex,address) values<foreach collection="users" item="user" separator=",">(#{user.username},#{user.birthday},#{user.sex},#{user.address})</foreach></update>
在这个例子中,deleteMoreByArray 方法会根据传入的 ids 数组动态生成批量删除的 SQL 语句。
4. SQL 注入问题及防范
SQL 注入是一种常见的安全漏洞,攻击者可以通过在输入中插入恶意 SQL 代码来操纵数据库查询。MyBatis 通过使用 #{} 占位符来防止 SQL 注入。
4.1 #{} 与 ${} 的区别
-
#{}:MyBatis 会使用预编译语句(PreparedStatement)来处理参数,参数会被安全地转义,从而防止 SQL 注入。 -
${}:MyBatis 会直接将参数拼接到 SQL 语句中,存在 SQL 注入的风险。
以下是一个使用 #{} 的示例:
<select id="findById" resultType="com.qcby.entity.User" parameterType="java.lang.Integer">SELECT * FROM user WHERE id = #{id}
</select>
在这个例子中,#{} 会确保 id 参数被安全地处理,防止 SQL 注入。
4.2 防范 SQL 注入的最佳实践
-
始终使用
#{}:在大多数情况下,应使用#{}来处理参数,避免使用${}。 -
避免动态拼接 SQL:尽量避免在 SQL 语句中动态拼接用户输入的内容。
-
使用 MyBatis 的动态 SQL 标签:通过使用
<if>、<choose>等标签,可以安全地构建动态 SQL 语句。
5. 总结
MyBatis 提供了强大的动态 SQL 功能,使得我们可以根据不同的条件灵活地生成 SQL 语句。同时,MyBatis 通过 #{} 占位符有效地防止了 SQL 注入问题。在实际开发中,我们应充分利用 MyBatis 的动态 SQL 特性,并遵循最佳实践来确保应用的安全性。
通过本文,你应该对 MyBatis 的增删改查操作、动态 SQL 语句拼接以及 SQL 注入问题有了更深入的理解。希望这些内容能帮助你在实际项目中更好地使用 MyBatis。


参考文献:
-
MyBatis 官方文档
-
SQL 注入攻击与防御
相关文章:
MyBatis增删改查:静态与动态SQL语句拼接及SQL注入问题解析
MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作。本文将深入探讨 MyBatis 中的增删改查操作,重点讲解静态与动态 SQL 语句的拼接,并分析 S…...
在运维工作中,Lvs、nginx、haproxy工作原理分别是什么?
在运维工作中,LVS、NGINX和HAProxy都是常用的负载均衡和反向代理工具,它们在高可用性和负载均衡场景中发挥重要作用。以下是其原理和应用场景详解: LVS(Linux Virtual Server) 工作原理 LVS是基于Linux内核的负载均…...
linux学习(五)(服务器审查,正常运行时间负载,身份验证日志,正在运行的服务,评估可用内存)
服务器审查 在 Linux 中审查服务器的过程包括评估服务器的性能、安全性和配置,以确定需要改进的领域或任何潜在问题。审查的范围可以包括检查安全增强功能、检查日志文件、审查用户帐户、分析服务器的网络配置以及检查其软件版本。 Linux 以其稳定性和安全性而闻名…...
Java在小米SU7 Ultra汽车中的技术赋能
目录 一、智能驾驶“大脑”与实时数据 场景一:海量数据的分布式计算 场景二:实时决策的毫秒级响应 场景三:弹性扩展与容错机制 技术隐喻: 二、车载信息系统(IVI)的交互 场景一:Android Automo…...
开发环境搭建-02.后端环境搭建-熟悉项目结构
一.后端环境搭建...
js实现pdf文件路径预览和下载
预览 直接浏览器窗口打开默认就是预览 window.open(文件路径)下载 function downloadPDF(url, filename) {fetch(url).then(response > response.blob()).then(blob > {const link document.createElement(a);link.href URL.createObjectURL(blob);link.download fi…...
【RAG】基于向量检索的 RAG (BGE示例)
RAG机器人 结构体 文本向量化: 使用 BGE 模型将文档和查询编码为向量。 (BGE 是专为检索任务优化的开源 Embedding 模型,除了本文API调用,也可以通过Hugging Face 本地部署BGE 开源模型) 向量检索: 从数据库中找到与查询相关的文…...
Vue源码解析之mustache模板引擎
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
python: DDD using postgeSQL and SQL Server
postgreSQL 注意: # psycopg 2 驱动的连接字符串 #engine create_engine(postgresql://post:geovindulocalhost:5433/TechnologyGame) #Session sessionmaker(bindengine)# 使用 psycopg3 驱动的连接字符串 #engine create_engine(postgresqlpsycopg://user:g…...
Python实例:PyMuPDF实现PDF翻译,英文翻译为中文,并按段落创建中文PDF
基于PyMuPDF与百度翻译的PDF翻译处理系统开发:中文乱码解决方案与自动化排版实践 一 、功能预览:将英文翻译为中文后创建的PDF 二、完整代码 from reportlab.lib.pagesizes import letter from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle...
IntelliJ IDEA 2021版创建springboot项目的五种方式
第一种方式,通过https://start.spring.io作为spring Initializr的url来创建项目。 第二种方式,通过https://start.spring.io官网来直接创建springboot项目压缩包,然后导入至我们的idea中。 点击generate后,即可生成压缩包…...
c#面试题整理6
1.String类能否被继承,为什么 可以看到String类的修饰符是sealed,即是密封类,故不可被继承 2.一个对象的方法是否只能由一个线程访问 不是,但是可通过同步机制,确保同一个时间只有一个线程访问 3.计算2*8ÿ…...
跟着 Lua 5.1 官方参考文档学习 Lua (12)
文章目录 5.7 – Input and Output Facilities补充内容io.input ([file])io.read ()io.write ()io.output ([file])io.lines ([filename])io.flush ()io.close ([file])io.open (filename [, mode])io.popen (prog [, mode])io.tmpfile ()io.type (ob)file:read ()file:lines (…...
大语言模型中的归一化技术:LayerNorm与RMSNorm的深入研究
在LLama等大规模Transformer架构的语言模型中,归一化模块是构建网络稳定性的关键组件。本文将系统分析归一化技术的必要性,并详细阐述为何原始Transformer架构中的LayerNorm在LLama模型中被RMSNorm所替代的技术原理。 归一化技术的基础原理 归一化的核…...
nodejs使用WebSocket实现聊天效果
在nodejs中使用WebSocket实现聊天效果(简易实现) 安装 npm i ws 实现 创建 server.js /*** 创建一个 WebSocket 服务器,监听指定端口,并处理客户端连接和消息。** param {Object} WebSocket - 引入的 WebSocket 模块,…...
【仿muduo库one thread one loop式并发服务器实现】
文章目录 一、项目介绍1-1、项目总体简介1-2、项目开发环境1-3、项目核心技术1-4、项目开发流程1-5、项目如何使用 二、框架设计2-1、功能模块划分2-1-1、SERVER模块2-1-2、协议模块 2-2、项目蓝图2-2-1、整体图2-2-2、模块关系图2-2-2-1、Connection 模块关系图2-2-2-2、Accep…...
10.2 继承与多态
文章目录 继承多态 继承 继承的作用是代码复用。派生类自动获得基类的除私有成员外的一切。基类描述一般特性,派生类提供更丰富的属性和行为。在构造派生类时,其基类构造函数先被调用,然后是派生类构造函数。在析构时顺序刚好相反。 // 基类…...
Go红队开发—格式导出
文章目录 输出功能CSV输出CSV 转 结构体结构体 转 CSV端口扫描结果使用CSV格式导出 HTML输出Sqlite输出nmap扫描 JSONmap转json结构体转jsonjson写入文件json编解码json转结构体json转mapjson转string练习:nmap扫描结果导出json格式 输出功能 在我们使用安全工具的…...
线性代数之矩阵特征值与特征向量的数值求解方法
文章目录 前言1. 幂迭代法(Power Iteration)幂法与反幂法求解矩阵特征值幂法求最大特征值编程实现补充说明 2. 逆幂迭代法(Inverse Iteration)移位反幂法 3. QR 算法(QR Algorithm)——稠密矩阵理论推导编程…...
Spring MVC源码分析のinit流程
文章目录 前言一、 init1.1、createWebApplicationContext1.2、onRefresh 二、请求处理器2.1、RequestMapping2.2、Controller接口2.3、HttpRequestHandler接口2.4、HandlerFunction 三、initHandlerMappings3.1、getDefaultStrategies3.1.1、RequestMappingHandlerMapping3.1.…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
