MyBatis动态SQL(if、choose、when和otherwise)标签

动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询

动态 SQL 只有几个基本元素,与 JSTL 或 XML 文本处理器相似,十分简单明了,大量的判断都可以在 MyBatis 的映射 XML 文件里配置,以达到许多需要大量代码才能实现的功能。动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性

if标签:条件判断

MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句

if 语句使用方法简单,常常与 test 属性联合使用。语法如下

html 复制代码
<if test="判断条件">
    SQL语句
</if>

当判断条件为 true 时,才会执行所包含的 SQL 语句。

最常见的场景是在 if 语句中包含 where 子句,例如

html 复制代码
<select id="selectAllWebsite" resultMap="myResult">
    select id,name,url from website
    <if test="name != null">
        where name like #{name}
    </if>
</select>

以上代表表示根据网站名称去查找相应的网站信息,但是网站名称是一个可填可不填的条件,不填写的时候不作为查询条件。

可多个 if 语句同时使用。以下语句表示为可以按照网站名称(name)或者网址(url)进行模糊查询。如果您不输入名称或网址,则返回所有的网站记录。但是,如果你传递了任意一个参数,它就会返回与给定参数相匹配的记录。

html 复制代码
<select id="selectAllWebsite" resultMap="myResult">
    select id,name,url from website where 1=1
    <if test="name != null">
        AND name like #{name}
    </if>
    <if test="url!= null">
        AND url like #{url}
    </if>
</select>

choose、when和otherwise标签

MyBatis 中动态语句 choose-when-otherwise 类似于 Java 中的 switch-case-default 语句。由于 MyBatis 并没有为 if 提供对应的 else 标签,如果想要达到<if>...<else>...</else> </if> 的效果,可以借助 <choose>、<when>、<otherwise> 来实现。

动态语句 choose-when-otherwise 语法如下

html 复制代码
<choose>
    <when test="判断条件1">
        SQL语句1
    </when >
    <when test="判断条件2">
        SQL语句2
    </when >
    <when test="判断条件3">
        SQL语句3
    </when >
    <otherwise>
        SQL语句4
    </otherwise>
</choose>

choose 标签按顺序判断其内部 when 标签中的判断条件是否成立,如果有一个成立,则执行相应的 SQL 语句,choose 执行结束;如果都不成立,则执行 otherwise 中的 SQL 语句。这类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

示例

以下示例要求:

  • 当网站名称不为空时,只用网站名称作为条件进行模糊查询;
  • 当网站名称为空,而网址不为空时,则用网址作为条件进行模糊查询;
  • 当网站名称和网址都为空时,则要求网站年龄不为空。

WebsiteMapper.xml 代码如下

html 复制代码
<mapper namespace="net.cc.mapper.WebsiteMapper">
    <select id="selectWebsite"
        parameterType="net.cc.po.Website"
        resultType="net.cc.po.Website">
        SELECT id,name,url,age,country
        FROM website WHERE 1=1
        <choose>
            <when test="name != null and name !=''">
                AND name LIKE CONCAT('%',#{name},'%')
            </when>
            <when test="url != null and url !=''">
                AND url LIKE CONCAT('%',#{url},'%')
            </when>
            <otherwise>
                AND age is not null
            </otherwise>
        </choose>
    </select>
</mapper>

测试类代码

java 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 读取配置文件mybatis-config.xml
        InputStream config = Resources.getResourceAsStream("mybatis-config.xml"); // 根据配置文件构建
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
        // 通过SqlSessionFactory创建SqlSession
        SqlSession ss = ssf.openSession();
        Website site = new Website();
        site.setname("编程");
        List<Website> siteList = ss.selectList("net.cc.mapper.WebsiteMapper.selectWebsite", site);
        for (Website ws : siteList) {
            System.out.println(ws);
        }
    }
}
相关推荐
带刺的坐椅4 分钟前
SolonCode v0.0.20 发布 - 编程智能体(新增子代理和浏览器能力)
java·ai·agent·solon·solon-ai·claude-code·openclaw
会员源码网1 小时前
数字格式化陷阱:如何优雅处理 NumberFormatException
java
孔明click332 小时前
Sa-Token v1.45.0 发布 🚀,正式支持 Spring Boot 4、新增 Jackson3/Snack4 插件适配
java·sa-token·开源·springboot·登录·权限认证
程序猿阿越2 小时前
Kafka4源码(二)创建Topic
java·后端·源码阅读
悟空码字2 小时前
Spring Boot 整合 MongoDB 最佳实践:CRUD、分页、事务、索引全覆盖
java·spring boot·后端
省长2 小时前
Sa-Token v1.45.0 发布 🚀,正式支持 Spring Boot 4、新增 Jackson3/Snack4 插件适配
java·后端·开源
NE_STOP3 小时前
MyBatis-动态sql与高级映射
java
后端AI实验室3 小时前
我把同一个需求分别交给初级程序员、高级程序员和AI,结果让我沉默了
java·ai
sTone873753 小时前
web后端开发概念: VO 和 PO
java·后端·架构
SimonKing4 小时前
JetBrains+Qoder变身Agentic 编码平台,媲美Cursor、Trae等AI编程平台
java·后端·程序员