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);
        }
    }
}
相关推荐
num_killer7 小时前
小白的Langchain学习
java·python·学习·langchain
期待のcode7 小时前
Java虚拟机的运行模式
java·开发语言·jvm
程序员老徐7 小时前
Tomcat源码分析三(Tomcat请求源码分析)
java·tomcat
a程序小傲8 小时前
京东Java面试被问:动态规划的状态压缩和优化技巧
java·开发语言·mysql·算法·adb·postgresql·深度优先
仙俊红8 小时前
spring的IoC(控制反转)面试题
java·后端·spring
阿湯哥8 小时前
AgentScope Java 集成 Spring AI Alibaba Workflow 完整指南
java·人工智能·spring
小楼v8 小时前
说说常见的限流算法及如何使用Redisson实现多机限流
java·后端·redisson·限流算法
与遨游于天地8 小时前
NIO的三个组件解决三个问题
java·后端·nio
czlczl200209258 小时前
Guava Cache 原理与实战
java·后端·spring
yangminlei9 小时前
Spring 事务探秘:核心机制与应用场景解析
java·spring boot