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);
        }
    }
}
相关推荐
yuzhiboyouye11 小时前
后端怎么评估工作量
java
java资料站11 小时前
十五、Spring AI Alibaba · 高级 ·Graph
java·人工智能·spring
the局外人11 小时前
学会 SQLAlchemy 搭建 Python 与 MySQL 之间的数据访问桥梁 🚀
后端·python·sql
冰暮流星11 小时前
mysql索引失效的情形
数据库·笔记·sql·mysql
金銀銅鐵12 小时前
[Java] 用 GUI 展示 ArrayList 扩容的过程
java·后端·ai编程
磊 子12 小时前
什么是虚假唤醒(spurious wakeup)?从 POSIX 标准讲到 futex 内核
java·开发语言
Navicat中国12 小时前
SQL 编辑器生产力:重构与实时错误检测
数据库·sql·重构·编辑器·navicat
飘然生12 小时前
traceId链路 skywalking java agent
java·开发语言·skywalking
IT研究室12 小时前
最新计算机毕业设计选题推荐-基于spring boot的母婴全程服务管理系统-网站-文档指导-Java-springboot
java·spring boot·课程设计
CRMEB12 小时前
商品 SKU 设计,从简单规格到多规格踩过什么
java·前端·数据库·开源