首页 > 数据库 >MyBatis 动态 SQL 详解与实践

MyBatis 动态 SQL 详解与实践

时间:2025-01-05 11:25:15浏览次数:1  
标签:userName 标签 查询 详解 user SQL MyBatis 动态

MyBatis 动态 SQL 详解与实践

引言

在开发中,我们经常需要根据不同的条件动态生成 SQL 语句。如果使用传统的 JDBC 或其他框架,拼接 SQL 语句会非常繁琐且容易出错。MyBatis 提供了强大的动态 SQL 功能,能够帮助我们轻松应对复杂的查询需求。本文将详细介绍 MyBatis 动态 SQL 的常用标签及其使用场景,并结合实际案例进行演示。


什么是动态 SQL?

动态 SQL 是 MyBatis 的核心特性之一,它允许我们根据不同的条件动态生成 SQL 语句。通过使用 MyBatis 提供的动态 SQL 标签,我们可以避免手动拼接 SQL 的繁琐操作,同时减少出错的可能性。

动态 SQL 的优势

  1. 灵活性:根据条件动态生成 SQL 语句。
  2. 简洁性:减少手动拼接 SQL 的代码量。
  3. 可维护性:动态 SQL 更易于阅读和维护。

动态 SQL 常用标签

MyBatis 提供了多种动态 SQL 标签,以下是常用的几种:

标签名称 作用描述
<if> 条件判断,用于根据条件动态拼接 SQL 片段。
<choose> 多条件分支判断,类似于 Java 中的 switch 语句。
<when> <choose> 配合使用,表示一个分支条件。
<otherwise> <choose> 配合使用,表示默认分支。
<trim> 用于去除 SQL 语句中多余的关键字(如 ANDOR)或符号(如逗号)。
<where> 动态生成 WHERE 子句,并去除多余的 ANDOR
<set> 动态生成 SET 子句,并去除多余的逗号。
<foreach> 遍历集合或数组,常用于 IN 查询或批量操作。

动态 SQL 实践案例

1. <if> 标签:条件判断

需求:查询男性用户,如果输入了用户名,则按用户名模糊查询;如果没有输入用户名,则查询所有男性用户。

接口方法

List<User> queryLikeUserName(@Param("userName") String userName);

SQL 映射

<select id="queryLikeUserName" resultType="User">
    SELECT * FROM tb_user WHERE sex = '男'
    <if test="userName != null and userName.trim() != ''">
        AND user_name LIKE '%${userName}%'
    </if>
</select>

测试

@Test
public void testQueryLikeUserName() {
    List<User> users = userMapper.queryLikeUserName("张");
    users.forEach(System.out::println);
}

说明

  • <if> 标签用于判断 userName 是否为空,如果不为空,则拼接模糊查询条件。
  • 注意:${} 用于直接拼接字符串,#{} 用于预编译参数。

2. <choose><when><otherwise> 标签:多条件分支

需求:根据用户名或住址查询男性用户。如果输入了用户名,则按用户名模糊查询;如果输入了住址,则按住址查询;如果两者都未输入,则查询用户名为“孙悟空”的用户。

接口方法

List<User> queryByUserNameOrAddress(
    @Param("userName") String userName, 
    @Param("address") String address
);

SQL 映射

<select id="queryByUserNameOrAddress" resultType="User">
    SELECT * FROM tb_user WHERE sex = '男'
    <choose>
        <when test="userName != null and userName.trim() != ''">
            AND user_name LIKE '%${userName}%'
        </when>
        <when test="address != null and address.trim() != ''">
            AND address = #{address}
        </when>
        <otherwise>
            AND user_name = '孙悟空'
        </otherwise>
    </choose>
</select>

测试

@Test
public void testQueryByUserNameOrAddress() {
    List<User> users = userMapper.queryByUserNameOrAddress(null, "花果山");
    users.forEach(System.out::println);
}

说明

  • <choose> 类似于 Java 中的 switch 语句,<when> 表示分支条件,<otherwise> 表示默认分支。

3. <where> 标签:动态生成 WHERE 子句

需求:根据用户名和住址查询用户。如果输入了用户名,则按用户名查询;如果输入了住址,则按住址查询;如果两者都输入,则同时满足两个条件。

接口方法

List<User> queryByUserNameAndAddress(
    @Param("userName") String userName, 
    @Param("address") String address
);

SQL 映射

<select id="queryByUserNameAndAddress" resultType="User">
    SELECT * FROM tb_user
    <where>
        <if test="userName != null and userName.trim() != ''">
            AND user_name = #{userName}
        </if>
        <if test="address != null and address.trim() != ''">
            AND address = #{address}
        </if>
    </where>
</select>

测试

@Test
public void testQueryByUserNameAndAddress() {
    List<User> users = userMapper.queryByUserNameAndAddress("孙悟空", null);
    users.forEach(System.out::println);
}

说明

  • <where> 标签会自动生成 WHERE 关键字,并去除多余的 ANDOR

4. <set> 标签:动态生成 SET 子句

需求:根据用户 ID 更新用户信息。如果某个字段为 null,则不更新该字段。

接口方法

void updateSelectiveUser(User user);

SQL 映射

<update id="updateSelectiveUser">
    UPDATE tb_user
    <set>
        <if test="userName != null and userName.trim() != ''">
            user_name = #{userName},
        </if>
        <if test="address != null and address.trim() != ''">
            address = #{address},
        </if>
    </set>
    WHERE id = #{id}
</update>

测试

@Test
public void testUpdateSelectiveUser() {
    User user = new User();
    user.setId(1);
    user.setUserName("悟空");
    userMapper.updateSelectiveUser(user);
}

说明

  • <set> 标签会自动生成 SET 关键字,并去除多余的逗号。

5. <foreach> 标签:遍历集合

需求:根据多个用户 ID 查询用户信息。

接口方法

List<User> queryByIds(@Param("ids") List<Integer> ids);

SQL 映射

<select id="queryByIds" resultType="User">
    SELECT * FROM tb_user WHERE id IN
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
</select>

测试

@Test
public void testQueryByIds() {
    List<Integer> ids = Arrays.asList(1, 2, 3);
    List<User> users = userMapper.queryByIds(ids);
    users.forEach(System.out::println);
}

说明

  • <foreach> 标签用于遍历集合或数组,常用于 IN 查询或批量操作。

总结

MyBatis 的动态 SQL 功能极大地简化了复杂查询的实现过程。通过灵活使用 <if><choose><where><set><foreach> 等标签,我们可以轻松应对各种动态查询需求。希望本文的内容能够帮助你更好地掌握 MyBatis 动态 SQL 的使用技巧,提升开发效率!


版权声明:本文为原创文章,转载请注明出处。

互动话题
你在使用 MyBatis 动态 SQL 时遇到过哪些问题?欢迎在评论区分享你的经验和心得!如果你有其他技术问题,也欢迎留言讨论!

标签:userName,标签,查询,详解,user,SQL,MyBatis,动态
From: https://www.cnblogs.com/itcq1024/p/18653206

相关文章

  • MyBatis 中 SQL 语句是否需要分号?——从 MySQL 习惯到 MyBatis 实践
    MyBatis中SQL语句是否需要分号?——从MySQL习惯到MyBatis实践引言在日常开发中,许多开发者习惯在MySQL客户端中书写SQL语句时以分号;结尾。然而,当我们将这种习惯带入MyBatis的映射文件(如mapper.xml)中时,可能会遇到一些意想不到的问题。本文将通过一个实际案例,详细......
  • sql server版本太老,java客户端连接失败问题定位
    背景最近半路接手了一个系统的优化需求,这个系统有个遗留问题还没解决,随着新需求的上线,系统正式开放使用,这个遗留问题也必须解决。这个系统大概是下面这样的,支持录入各种数据源的信息(ip、端口、数据库种类、账号密码等):录入完成后,可以查看这些数据源中的表、表的ddl、表中的列(列......
  • (免费送源码)计算机毕业设计原创定制:Java+SpringBoot+MySQL SpringBoot宠物领养管理平台
     摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,宠物行业当然也不例外。宠物领养管理平台是以实际运用为开发背景,运用软件工程原理和开发方法,采用Java技术构建的一个管理系统。整个开发过程首先对软件系统......
  • Java 中的 getDeclaredMethod() 方法:使用与原理详解
    在Java反射机制中,getDeclaredMethod()是一个非常重要的方法,用于获取类中声明的特定方法(包括公共、保护、默认和私有方法)。与getMethod()不同,getDeclaredMethod()可以访问类的所有方法,而不仅仅是公共方法。本文将深入探讨getDeclaredMethod()的使用方法、原理以及实......
  • DVWA靶场Command Injection(命令注入) 漏洞所有级别通关教程详解及源码审计
    目录标题前言命令注入low源码审计medium源码审计high源码审计impossible源码审计前言本人公众号:泷羽Sec-track,感兴趣的师傅可以看看命令注入命令注入漏洞是一种安全漏洞,攻击者可以通过向应用程序输入恶意命令,诱使系统执行这些命令,从而达到未授权访问、数据篡......
  • Python+Django+Mysql开发个性化旅游酒店推荐系统 python在线酒店推荐系统设计开发 可
    Python+Django+Mysql开发个性化旅游酒店推荐系统python在线酒店推荐系统设计开发可视化、爬虫协同过滤推荐算法机器学习深度学习人工智能大数据开发教程文档HotelRecommendSysPy一、项目简介1、开发工具和使用技术Python3及以上版本,Django3.6及以上版本,mysql8,nav......
  • Log Parser Lizard 8.7:一款用于高级日志分析的动态图形界面工具,使用 SQL 查询多种结构
    LogParserLizard:AdvancedSQLAnalysisforLogFiles LogParserLizard version 8.7lizardlabs(LizardLabsSoftware)·GitHubLogParserLizard:一款用于高级日志分析的动态图形界面工具使用SQL查询多种结构化日志数据,包括服务器日志和Windows事件日志。体......
  • 【跟着官网学技术系列之MySQL】第1天之MySQL 数据库管理系统概述
    前言在当今信息爆炸的时代,拥有信息检索的能力很重要。作为一名软件工程师,遇到问题,你会怎么办?带着问题去搜索引擎寻找答案?亦或是去技术官网,技术社区去寻找?根据个人经验,一般遇到问题,基本搜索引擎都可以解决(抱着:我遇到的问题肯定别人也遇到过的心态去解决)实在解决不了的,逛......
  • 在electron中使用sqlite
    一、安装pnpminstallknexbetter-sqlite3还需要再执行npxelectron-rebuild-v二、注册ICP然后再主进程中://mian.jsconstknex=require('knex');constdb=knex({client:'better-sqlite3',connection:{filename:path.join(__dirname,'exam......
  • PL/SQL语言的并发编程
    PL/SQL语言的并发编程引言在现代数据库应用中,通常需要处理大量的数据,并发编程成为了提升系统性能的有效手段。PL/SQL(ProceduralLanguage/SQL)作为Oracle数据库的一种过程化语言,具备强大的数据处理能力。在大规模数据处理和事务管理中,PL/SQL的并发编程能力显得尤为重要。本......