// 传统方式需要手动拼接SQL字符串
StringBuilder sql = new StringBuilder("SELECT * FROM orders WHERE 1=1");
if (status != null) {
sql.append(" AND status = '").append(status).append("'");
}
// 存在SQL注入风险!且代码冗长难维护
与
标签
标签:基础条件判断<select id="findUsers" resultType="User">
SELECT * FROM user
<where>
<if test="id != null">
AND id = #{id}
if>
<if test="username != null">
AND username = #{username}
if>
where>
select>
标签:智能WHERE处理错误示例:
SELECT * FROM user
WHERE
<if test="id != null">id = #{id}if>
标签<select id="getUser" resultType="User">
SELECT * FROM user
<where>
<choose>
<when test="id != null">
id = #{id}
when>
<when test="username != null">
username = #{username}
when>
<otherwise>
1=0
otherwise>
choose>
where>
select>
适用场景:
执行特点:
标签<update id="updateUser" parameterType="User">
UPDATE user
<set>
<if test="username != null">
username = #{username},
if>
<if test="password != null">
password = #{password},
if>
<if test="age != null">
age = #{age}
if>
set>
WHERE id = #{id}
update>
核心优势:
Java调用示例:
User user = new User();
user.setId(4);
user.setUsername("小王");
// 只更新用户名,密码和年龄保持不变
int rows = userRepository.update(user);
生成SQL:
UPDATE user SET username = ? WHERE id = ?
标签<select id="getByIds" resultType="User">
SELECT * FROM user
<where>
<foreach collection="ids" item="id"
open="id IN (" close=")" separator=",">
#{id}
foreach>
where>
select>
参数说明:
属性 | 作用 | 示例值 |
---|---|---|
collection |
集合参数名 | ids |
item |
迭代元素变量名 | id |
open |
循环开始时的字符串 | ( |
close |
循环结束时的字符串 | ) |
separator |
元素间的分隔符 | , |
Java调用:
User query = new User();
query.setIds(Arrays.asList(1, 3, 4));
List<User> users = userRepository.getByIds(query);
生成SQL:
SELECT * FROM user WHERE id IN (1, 3, 4)
<insert id="batchInsert">
INSERT INTO user (username, email) VALUES
<foreach collection="users" item="user" separator=",">
(#{user.username}, #{user.email})
foreach>
insert>
<bind name="namePattern" value="'%' + name + '%'"/>
AND username LIKE #{namePattern}
<if test="username != null and username != ''">
// 开启SQL日志
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
日志输出:
==> Preparing: SELECT * FROM user WHERE id IN ( ? , ? , ? )
==> Parameters: 1(Integer), 3(Integer), 4(Integer)
标签 | 应用场景 | 关键特性 |
---|---|---|
|
条件判断 | 支持多条件组合 |
|
WHERE子句生成 | 智能处理AND/OR前缀 |
|
多选一逻辑 | 类似switch-case,只选一个条件 |
|
UPDATE语句生成 | 自动处理逗号后缀 |
|
遍历集合操作 | 支持IN查询、批量操作 |
组合使用:标签可嵌套使用应对复杂场景
<select id="complexQuery">
SELECT * FROM orders
<where>
<if test="status != null">
status = #{status}
if>
<if test="productIds != null">
AND product_id IN
<foreach collection="productIds" item="id" open="(" close=")" separator=",">
#{id}
foreach>
if>
where>
ORDER BY
<choose>
<when test="sortBy == 'price'">pricewhen>
<otherwise>create_timeotherwise>
choose>
select>
适用场景:
性能数据:
架构师建议:当动态SQL超过20个条件时,考虑改用Elasticsearch等专业搜索方案。
思考题:当动态SQL生成的查询在测试环境正常,生产环境却出现性能问题,你会如何排查?欢迎分享你的实战经验!