第4章-MyBatis实践之动态语句
MyBatis 是一款优秀的持久层框架,它的强大之处正是 SQL 语句映射,这一章介绍常用的动态 SQL。
详细配置参阅《MyBatis介绍与配置》
增删改查参阅《MyBatis实践之增删改查》
一、 概述
动态 SQL 是 MyBatis 的强大特性之一,通过不同参数生成不同的 SQL,可以动态地对数据持久层进行操作,而不需要每个数据访问操作都要进行手动地拼接 SQL 语句。
二、动态语句
1. if
<if>
语句可以根据条件指定 SQL 部分,例如 where
条件。
查询数据接口如下:
public interface UserSqlMapper {
List<User> selectByUsername(@Param("username") String username, @Param("status") Integer status);
}
对应映射语句如下:
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user WHERE 1 = 1
<if test="status != null">
AND status = #{status}
</if>
<if test="username != null and username != ''">
AND username = #{username}
</if>
</select>
上面语句当 status
不为 null
时,以及 username
不为空字符串时,对应的查询条件才会生效。
2. choose、when、otherwise
<choose>
语句类似于 Java 的 switch
语句,可以从多个条件中选择一个使用。
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user WHERE 1 = 1
<choose>
<when test="status != null">
AND status = #{status}
</when>
<otherwise>
AND username = #{username}
</otherwise>
</choose>
</select>
上面语句根据 status
是否为 null
而执行不同的查询条件,每次查询只存在一个查询条件。
3. trim、where、set
在前面的例子中,where
后面都会加上 1=1
这个条件,为了解决当所有条件都没生效时,where
条件为空而产生异常的问题。
在更新语句 set
后面也会出现同样的问题,可以使用 <trim>
语句通过指定前缀和后缀的方式来解决。
MyBatis 也提供更简单的 <where>
语句和 <set>
语句来解决这个问题。
例如下面两个接口:
public interface UserSqlMapper {
List<User> selectByUsername(@Param("username") String username, @Param("status") Integer status);
void updateById(User user);
}
对应的 <trim>
映射 where
语句如下:
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="status != null">
AND status = #{status}
</if>
<if test="username != null and username != ''">
AND username = #{username}
</if>
</trim>
</select>
对应的 <where>
映射语句如下:
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user
<where>
<if test="status != null">
AND status = #{status}
</if>
<if test="username != null and username != ''">
AND username = #{username}
</if>
</where>
</select>
对应的 <trim>
映射 update
语句如下:
<update id="updateById">
UPDATE t_user
<trim prefix="SET" suffixOverrides=",">
<if test="status != null">
status = #{status},
</if>
<if test="username != null and username != ''">
username = #{username},
</if>
</trim>
</update>
对应的 <set>
映射语句如下:
<update id="updateById">
UPDATE t_user
<set>
<if test="status != null">
status = #{status},
</if>
<if test="username != null and username != ''">
username = #{username},
</if>
</set>
</update>
4. foreach
<foreach>
可以对集合进行遍历,例如使用 IN
条件语句的时候。
查询数据接口如下:
public interface UserSqlMapper {
List<User> selectInIdList(@Param("idList") List<Long> idList);
}
对应映射语句如下:
<select id="selectInIdList" resultType="User">
SELECT * FROM t_user
<where>
<foreach item="item" index="index" collection="idList" open="id IN (" separator="," close=")" nullable="true">
#{item}
</foreach>
</where>
</select>
item
指定元素,index
指定索引。
5. script
<script>
可以在接口上的注解中使用动态SQL。
例如查询数据接口如下:
public interface UserSqlMapper {
@Select("<script>" +
"SELECT * FROM t_user" +
"<where>" +
" <if test='status != null'>AND status = #{status}</if>" +
" <if test='username != null'>AND username = #{username}</if>" +
"</where>" +
"</script>")
List<User> selectByUser(User user);
}
<script>
标签里面的内容和在 XML 文件中的动态 SQL 语法一致。
三、附录
1. 示例代码
Gitee 仓库:https://gitee.com/code_artist/mybatis
2. 参考文献
MyBatis 3 官方文档:https://mybatis.org/mybatis-3/zh/
本文来自博客园,作者:码匠_CodeArtist,转载请注明原文链接:https://www.cnblogs.com/code-artist/p/mybatis-4.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY