MyBatis动态SQL与MyBatis Generator插件使用教程
作者:稻草猫.
一.动态SQL
动态 SQL 是Mybatis的强大特性之⼀,能够完成不同条件下不同的 sql 拼接
下面我只介绍比较常用的动态SQL标签 ,想要了解更多标签可以参考官方文档:https://mybatis.net.cn/dynamic-sql.html
1.1 <if> 标签
if 标签 是 MyBatis 动态 SQL 最常用的标签,作用是根据条件动态拼接 SQL 片段,解决「不同条件下执行不同 SQL」的问题,比如多条件查询、非空字段更新 / 插入等场景。
语法:
<if test="条件表达式">
需要拼接的 SQL 片段
</if>接口定义:
Integer insertUserByCondition(UserInfo userInfo);
Mapper.xml 实现:
<insert id="insertUserByCondition">
INSERT INTO userinfo (
username,
`password`,
age,
<if test="gender != null">
gender,
</if>
phone)
VALUES (
#{username},
#{age},
<if test="gender != null">
#{gender},
</if>
#{phone})
</insert>使用注解实现(不推荐):
把上面SQL(包括标签),使用<script></script>标签括起来就可以
@Insert("<script>" +
"INSERT INTO userinfo (username,`password`,age," +
"<if test='gender!=null'>gender,</if>" +
"phone)" +
"VALUES(#{username},#{age}," +
"<if test='gender!=null'>#{gender},</if>" +
"#{phone})"+
"</script>")
Integer insertUserByCondition(UserInfo userInfo);1.2 <trim>标签
<trim> 是 MyBatis 中用于修剪 SQL 片段首尾多余字符的标签,常配合<if> 使用,解决「动态拼接 SQL 时首尾多出 AND/OR/ 逗号」的问题
语法:
<trim prefix="前缀" suffix="后缀" prefixOverrides="要移除的前缀字符" suffixOverrides="要移除的后缀字符">
动态拼接的 SQL 片段
</trim>| 属性 | 作用 | 示例值 |
|---|---|---|
prefix | 给拼接后的 SQL 片段添加前缀(比如 ( 或 WHERE) | prefix="WHERE" |
suffix | 给拼接后的 SQL 片段添加后缀(比如 ) 或 VALUES) | suffix=")" |
prefixOverrides | 移除拼接后 SQL 片段开头的指定字符(比如 AND/OR) | prefixOverrides="AND" |
suffixOverrides | 移除拼接后 SQL 片段结尾的指定字符(比如 ,) | suffixOverrides="," |
注意:它会根据内部动态拼接的 SQL 片段,自动决定是否添加前缀 / 后缀,以及是否移除首尾多余的字符,完全不需要我们手动判断
调整 Mapper.xml 的插入语句为:
<insert id="insertUserByCondition">
INSERT INTO userinfo
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username !=null">
username,
</if>
<if test="password !=null">
`password`,
</if>
<if test="age != null">
age,
</if>
<if test="gender != null">
gender,
</if>
<if test="phone != null">
phone,
</if>
</trim>
VALUES
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username !=null">
#{username},
</if>
<if test="password !=null">
#{password},
</if>
<if test="age != null">
#{age},
</if>
<if test="gender != null">
#{gender},
</if>
<if test="phone != null">
#{phone}
</if>
</trim>
</insert>1.3 <where>标签
<where> 是 MyBatis 为 WHERE 子句量身定制 的标签,本质是 <trim> 的「简化版」,专门解决「动态查询时 WHERE 子句的拼接问题」,比手动写<trim> 更简洁、语义更清晰。
核心语法:
<where>
<if test="条件1">AND/OR 条件1的SQL片段</if>
<if test="条件2">AND/OR 条件2的SQL片段</if>
<!-- 更多if条件 -->
</where>核心作用:
- 自动为条件块添加
WHERE关键字(仅当内部有有效条件时); - 自动剔除条件块开头多余的
AND或OR关键字。
注意:<where> 标签是 <trim perfix="where perfixOverrides = "AND" | "OR" > 的简化写法,规则完全一致。
接口定义:
List<UserInfo> queryByCondition();
Mapper.xml 实现:
<select id="queryByCondition" resultType="com.example.demo.model.UserInfo">
select id, username, age, gender, phone, delete_flag, create_time,
update_time
from userinfo
<where>
<if test="age != null">
and age = #{age}
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="deleteFlag != null">
and delete_flag = #{deleteFlag}
</if>
</where>
</select>1.4 <set> 标签
<set>是 MyBatis 提供的动态 SQL 核心标签,专用于 UPDATE 语句的 SET子句动态拼接,是<trim>标签针对更新场景的语法糖(简化封装),其核心定义可拆解为:
核心语法:
<update id="方法名" parameterType="参数类型(如实体类全限定名)">
UPDATE 表名
<set>
<!-- 动态更新字段:每个字段后可加逗号,<set> 自动处理 -->
<if test="字段名 != null [and 字段名 != '']">
数据库字段名 = #{参数名},
</if>
<!-- 可添加多个 <if> 标签,对应多个更新字段 -->
</set>
WHERE 主键字段 = #{主键参数} <!-- 必须加,防止全表更新 -->
</update>功能定位:解决手动拼接 UPDATE 语句的 SET 子句时,因字段条件动态变化导致的「末尾多余逗号」「无有效字段时生成空 SET 子句」等 SQL 语法错误问题;
核心规则:
- 仅当内部包含有效更新字段(非空的
<if>条件块)时,才会在拼接结果前添加SET关键字; - 自动剔除拼接结果末尾多余的英文逗号(
,); - 无有效更新字段时,不生成任何
SET相关内容(避免UPDATE table WHERE ...这类语法错误)。
注意:<set> 标签也可以使用 <trim prefix="set" suffixOverrides=","> 代替,这两个的功能完全一致
接口定义:
Integer updateUserByCondition(UserInfo userInfo);
Mapper.xml 实现:
<update id="updateUserByCondition">
update userinfo
<set>
<if test="username != null">
username = #{username},
</if>
<if test="age != null">
age = #{age},
</if>
<if test="deleteFlag != null">
delete_flag = #{deleteFlag},
</if>
</set>
where id = #{id}
</update>1.5 <foreach>标签
<foreach>标签是 MyBatis 框架中最常用的动态 SQL 标签之一,核心作用是遍历集合(List/Set/ 数组 / Map),并根据集合元素动态拼接 SQL 语句(比如批量插入、IN 条件查询等)。
<foreach>标签的核心属性如下(前 4 个是最常用的):
| 属性名 | 作用 |
|---|---|
collection | 绑定方法参数中的集合,如List,Set,Map或数组对象 |
item | 遍历时的每一个对象,给每一个对象取的别名 |
separator | 元素之间的分隔符 |
open | 语句块开头的字符串 |
close | 语句块结尾得字符串 |
接口定义:
void deleteByIds(List<Integer> ids);
Mapper.xml 实现:
<delete id="deleteByIds">
delete from userinfo
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>1.6 <include> 标签
<include> 标签是 MyBatis 中用于复用 SQL 片段的核心标签,能有效解决 SQL 代码冗余问题(比如多个 SQL 语句共用相同的字段列表、WHERE 条件等),提升代码的可维护性。
简单来说,<include>就像编程里的 “复制粘贴”,但更优雅 —— 你可以把重复的 SQL 片段定义在<sql> 标签里,然后在需要的地方用<include>引用它。
核心语法:
1. 定义可复用的sql片段(使用 <sql> 标签)
<sql id="allColumn"> id, username, age, gender, phone, delete_flag, create_time, update_time </sql>
2. 引用sql片段 (使用<include> 标签)
<select id="queryAllUser" resultMap="BaseMap">
select
<include refid="allColumn"></include>
from userinfo
</select>
<select id="queryById" resultType="com.example.demo.model.UserInfo">
select
<include refid="allColumn"></include>
from userinfo where id= #{id}
</select>总结使用流程:先通过<sql id="xxx">定义片段,再通过<include refid ="xxx">引用;
二. MyBatis Generator
MyBatis Generator是⼀个为MyBatis框架设计的代码成成⼯具, 它可以根据数据库表结构自动生成相应 的Java 实体类 , Mapper接口 以及SQL映射文件,简化数据访问层的编码工作,使得开发者可以更专注于 业务逻辑的实现. 接下来我们看下,如何使用 MyBatisGenerator来生成代码.
2.1 引入插件
<plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.6</version> <executions> <execution> <id>Generate MyBatis Artifacts</id> <phase>deploy</phase> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <!--generator配置⽂件所在位置 --> <configurationFile>src/main/resources/mybatisGenerator/generatorConfig.xml</con figurationFile> <!-- 允许覆盖⽣成的⽂件, mapxml不会覆盖, 采⽤追加的⽅式--> <overwrite>true</overwrite> <verbose>true</verbose> <!--将当前pom的依赖项添加到⽣成器的类路径中--> <includeCompileDependencies>true</includeCompileDependencies> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies> </plugin>
上面的有些内容属于模板,实际需要按情况进行修改,比如<configurationFile>中的路径要和你创建的文件的路径保持一致
2.2 添加generatorConfig.xml并修改
⽂件路径和上述配置保持⼀致:

完善文件内容
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <!-- 配置⽣成器 --> <generatorConfiguration> <!-- ⼀个数据库⼀个context --> <context id="MysqlTables" targetRuntime="MyBatis3Simple"> <!--禁⽤⾃动⽣成的注释--> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--数据库连接信息--> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/java_blog_spring? serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true" userId="root" password="root"> </jdbcConnection> <!-- ⽣成实体类, 配置路径 --> <javaModelGenerator targetPackage="com.example.demo.model" targetProject="src/main/java" > <property name="enableSubPackages" value="false"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- ⽣成mapxml⽂件 --> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources" > <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- ⽣成mapxml对应client,也就是接⼝mapper --> <javaClientGenerator targetPackage="com.example.demo.mapper" targetProject="src/main/java" type="XMLMAPPER" > <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- table可以有多个,tableName表⽰要匹配的数据库表 --> <table tableName="user" domainObjectName="UserInfo" enableSelectByExample="true" enableDeleteByExample="true" enableDeleteByPrimaryKey="true" enableCountByExample="true" enableUpdateByExample="true">
2.3 生成文件

双击运行即可根据 generatorConfig.xml 中的具体配置 生成一个表 的Java实体类,mapper接口,mapper接口对应的XML文件
到此这篇关于MyBatis动态SQL与MyBatis Generator插件使用教程的文章就介绍到这了,更多相关MyBatis Generator插件使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
