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

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 方法会根据 usernamesex 和 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 是一个优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作。本文将深入探讨 MyBatis 中的增删改查操作&#xff0c;重点讲解静态与动态 SQL 语句的拼接&#xff0c;并分析 S…...

在运维工作中,Lvs、nginx、haproxy工作原理分别是什么?

在运维工作中&#xff0c;LVS、NGINX和HAProxy都是常用的负载均衡和反向代理工具&#xff0c;它们在高可用性和负载均衡场景中发挥重要作用。以下是其原理和应用场景详解&#xff1a; LVS&#xff08;Linux Virtual Server&#xff09; 工作原理 LVS是基于Linux内核的负载均…...

linux学习(五)(服务器审查,正常运行时间负载,身份验证日志,正在运行的服务,评估可用内存)

服务器审查 在 Linux 中审查服务器的过程包括评估服务器的性能、安全性和配置&#xff0c;以确定需要改进的领域或任何潜在问题。审查的范围可以包括检查安全增强功能、检查日志文件、审查用户帐户、分析服务器的网络配置以及检查其软件版本。 Linux 以其稳定性和安全性而闻名…...

Java在小米SU7 Ultra汽车中的技术赋能

目录 一、智能驾驶“大脑”与实时数据 场景一&#xff1a;海量数据的分布式计算 场景二&#xff1a;实时决策的毫秒级响应 场景三&#xff1a;弹性扩展与容错机制 技术隐喻&#xff1a; 二、车载信息系统&#xff08;IVI&#xff09;的交互 场景一&#xff1a;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 模型将文档和查询编码为向量。 &#xff08;BGE 是专为检索任务优化的开源 Embedding 模型&#xff0c;除了本文API调用&#xff0c;也可以通过Hugging Face 本地部署BGE 开源模型&#xff09; 向量检索: 从数据库中找到与查询相关的文…...

Vue源码解析之mustache模板引擎

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…...

python: DDD using postgeSQL and SQL Server

postgreSQL 注意&#xff1a; # 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项目的五种方式

第一种方式&#xff0c;通过https://start.spring.io作为spring Initializr的url来创建项目。 第二种方式&#xff0c;通过https://start.spring.io官网来直接创建springboot项目压缩包&#xff0c;然后导入至我们的idea中。 点击generate后&#xff0c;即可生成压缩包&#xf…...

c#面试题整理6

1.String类能否被继承&#xff0c;为什么 可以看到String类的修饰符是sealed&#xff0c;即是密封类&#xff0c;故不可被继承 2.一个对象的方法是否只能由一个线程访问 不是&#xff0c;但是可通过同步机制&#xff0c;确保同一个时间只有一个线程访问 3.计算2*8&#xff…...

跟着 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架构的语言模型中&#xff0c;归一化模块是构建网络稳定性的关键组件。本文将系统分析归一化技术的必要性&#xff0c;并详细阐述为何原始Transformer架构中的LayerNorm在LLama模型中被RMSNorm所替代的技术原理。 归一化技术的基础原理 归一化的核…...

nodejs使用WebSocket实现聊天效果

在nodejs中使用WebSocket实现聊天效果&#xff08;简易实现&#xff09; 安装 npm i ws 实现 创建 server.js /*** 创建一个 WebSocket 服务器&#xff0c;监听指定端口&#xff0c;并处理客户端连接和消息。** param {Object} WebSocket - 引入的 WebSocket 模块&#xff0c…...

【仿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 继承与多态

文章目录 继承多态 继承 继承的作用是代码复用。派生类自动获得基类的除私有成员外的一切。基类描述一般特性&#xff0c;派生类提供更丰富的属性和行为。在构造派生类时&#xff0c;其基类构造函数先被调用&#xff0c;然后是派生类构造函数。在析构时顺序刚好相反。 // 基类…...

Go红队开发—格式导出

文章目录 输出功能CSV输出CSV 转 结构体结构体 转 CSV端口扫描结果使用CSV格式导出 HTML输出Sqlite输出nmap扫描 JSONmap转json结构体转jsonjson写入文件json编解码json转结构体json转mapjson转string练习&#xff1a;nmap扫描结果导出json格式 输出功能 在我们使用安全工具的…...

线性代数之矩阵特征值与特征向量的数值求解方法

文章目录 前言1. 幂迭代法&#xff08;Power Iteration&#xff09;幂法与反幂法求解矩阵特征值幂法求最大特征值编程实现补充说明 2. 逆幂迭代法&#xff08;Inverse Iteration&#xff09;移位反幂法 3. QR 算法&#xff08;QR Algorithm&#xff09;——稠密矩阵理论推导编程…...

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.…...

用数字逻辑门复刻柏林钟:从二进制编码到硬件实现

1. 项目概述&#xff1a;用数字电路复刻“柏林钟”作为一个在柏林长大的孩子&#xff0c;我从小就对库达姆大街上的那座“柏林钟”着迷。它不像传统时钟那样用指针或数字告诉你时间&#xff0c;而是通过几排不同颜色的发光方块&#xff0c;以一种近乎艺术的方式呈现时间。这种独…...

如何高效批量下载音乐歌词:智能歌词管理完整指南

如何高效批量下载音乐歌词&#xff1a;智能歌词管理完整指南 【免费下载链接】ZonyLrcToolsX ZonyLrcToolsX 是一个能够方便地下载歌词的小软件。 项目地址: https://gitcode.com/gh_mirrors/zo/ZonyLrcToolsX ZonyLrcToolsX 是一款专业的跨平台歌词下载工具&#xff0c…...

从BUG()到panic:深入Linux 5.4内核,看异常处理如何层层递进

从BUG()到panic&#xff1a;Linux内核异常处理的防御体系全解析当你在深夜调试一个内核模块时&#xff0c;突然屏幕刷出一串红色警告——这可能是每个Linux内核开发者都经历过的噩梦时刻。但你是否想过&#xff0c;从第一行警告出现到系统完全崩溃&#xff0c;内核究竟经历了怎…...

别再死记硬背了!用5个生活化比喻彻底搞懂Linux进程的fork、exec和wait

别再死记硬背了&#xff01;用5个生活化比喻彻底搞懂Linux进程的fork、exec和wait想象你正在厨房准备一顿大餐。菜谱上写着"切菜"、"炒菜"、"装盘"等步骤&#xff0c;但突然发现需要同时处理多道菜品——这时候&#xff0c;你会本能地让家人分工…...

网络配置工具类详解

CNet 网络配置工具类详解平台&#xff1a;仅支持 Linux&#xff0c;大量使用 ioctl 系统调用一、概述 CNet 是一个 纯静态方法的网络配置工具类&#xff0c;封装了 Linux 下常用的网络操作&#xff1a;功能类别涵盖内容IP 地址读取/设置本机 IP、子网掩码网关读取/添加/删除/设…...

WTF Auto Layout? 实战:10个常见约束冲突案例解析与解决方案

WTF Auto Layout? 实战&#xff1a;10个常见约束冲突案例解析与解决方案 【免费下载链接】wtfautolayout The source code for Why The Failure, Auto Layout? 项目地址: https://gitcode.com/gh_mirrors/wt/wtfautolayout 在iOS开发中&#xff0c;Auto Layout是构建灵…...

真可用!美团数字人模型开源,MV、电商等统统拿下

美团开源的数字人视频生成框架 LongCat-Video-Avatar 刚刚更新到 1.5 版本。是真能用。这版更新把音频编码器换了&#xff0c;推理步数砍到8步&#xff0c;在770人、13240条主观评分的大规模评测里&#xff0c;雷达图面积全面领先。音频编码器换血&#xff0c;8步出图LongCat-V…...

量子纠错码VarQEC:原理、实现与硬件优化

1. 量子纠错码基础与实验背景量子纠错码&#xff08;Quantum Error Correction Codes, QEC&#xff09;是量子计算中保护量子信息免受噪声影响的核心技术。与经典纠错码不同&#xff0c;量子纠错需要应对量子态特有的退相干和纠缠特性。传统QEC如[[5,1,3]]完美码虽然理论完备&a…...

Jetson Orin上TVA模型DLA精准卸载配置

重磅预告&#xff1a;本专栏将独家连载系列丛书《智能体视觉技术与应用》部分精华内容&#xff0c;该书是世界首套系统阐述“因式智能体”视觉理论与实践的专著&#xff0c;特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“…...

Unity新手避坑指南:NavMesh烘焙参数(Agent Radius/Height)到底怎么设?附场景实测

Unity导航系统深度解析&#xff1a;Agent参数设置与场景适配实战在Unity游戏开发中&#xff0c;导航系统(Navigation System)是实现角色智能移动的核心模块。对于刚接触Unity导航系统的开发者来说&#xff0c;Agent Radius(代理半径)和Agent Height(代理身高)这两个参数的设置往…...