MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

2025-04-03 03:50

本文主要是介绍MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感...

动态SQL详解

动态SQL是一种在运行时生成和执行SQL语句的技术,广泛应用于处理复杂查询条件和动态数据需求。以下是动态SQL的核心概念、常见用法及注意事项。

一、动态SQL的核心概念

1.1 什么是动态SQL?

动态SQL是一种灵活的SQL编写方式,允许开发者在程序运行时根据条件生成SQL语句,而不是在编译时固化。动态 SQL 是MyBATis的强大特性之一,能够完成不同条件下不同的 SQL拼接。

1.2 动态SQL的优点

  • 灵活性:根据不同条件生成不同的SQL语句。
  • 复用性:减少重复代码,提高代码维护性。
  • 性能:在某些场景下可以优化查询性能。

1.3 动态SQL的常见用途

  • 处理多条件查询。
  • 动态指定表名、字段或排序方式。
  • 处理批量操作。

二、动态SQL的常见用法(XML方式)

数据库数据信息

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

2.1 < if > 标签

主要用于在动态SQL中根据条件判断是否执行某个SQL片段。它可以根据传入的参数或条件动态地添加或移除SQL语句的一部分,从而实现灵活的查询需求。

UserInfoMapperXML.Java 接口代码

 Integer insertUserBySQL(UserInfo userInfo);

UserInfoMapper.xml 文件

    <insert id="insertUserBySQL">
        insert into user_info (
        username,
        password,
        age,
        <if test="gender!=null">
            gender,
        </if>
        phone)
        values(
        #{username},
        #{password},
        #{age},
        <if test="gender!=null">
            #{gender},
        </if>
        #{phone})
    </insert>

测试类没有插入gender的情况

    @Test
    JItHLbIvoid insertUserBySQL() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("qq");
        userInfo.setPassword("qq");
        userInfo.setAge(46);
        userInfo.setPhone("465131");
        userInfoMapperXML.insertUserBySQL(userInfo);
    }

运行结果:

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

可以看到把gender这个字段使用if标签之后,这个字段就被移除了。

2.2< trim>标签

trim标签在动态SQL中起到格式化SQL语句的作用,允许开发者在生成SQL时自动处理空格、换行符以及前缀后缀的添加。通过合理使用trim标签,可以简化动态SQL的开发,提高代码的可读性和维护性,同时确保生成的SQL语句高效且正确。

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

prefix:表示整个语句块,以prefix的值作为前缀
suffix:表示整个语句块,以suffixChina编程的值作为后缀
prefixOverrides:表示整个语句块要去除掉的前缀
suffixOverrides:表示整个语句块要去除掉的后缀

为了更好的了解trim标签的作用,先来个错误的示范。

XML.java 文件

Integer insertUserBySQL1(UserInfo userInfo);

.xml文件

    <insert id="insertUserBySQL1">
        insert into user_info
        <trim prefix="(" suffix=")" >
    <if test="username!=null">
        username,
    </if>
            <if test="password!=null">
                password,
            </if>
            <if test="age!=null">
                age,
            </if>
            <if test="gender!=null">
                gender,
            </if>
            <if test="phone!=null">
                phone
            </if>
        </trim>
        values
        <trim suffix="(" prefix=")" >
            <if test="username!=null">
                #{username},
            </if>
            <if test="password!=null">
                #{password},
            </if>
            <if test="age!=null">
                #{age},
            </if>
            <if test="gender!=null">
                #{gender},
            </if>
            <if test="phone">
                #{phone}
            </if>
        </trim>
    </insert>

测试类

 @Test
    void insertUserBySQL1() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("zhangs");
        userInfo.setPassword("123461");
        userInfo.setPhone("7489");
        userInfoMapperXML.insertUserBySQL1(userInfo);

运行结果:

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

修改 .xml文件,通过trim标签给SQL语句添加或者去除前后缀。

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

再进行测试;

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

可以看到成功了。

2.3 <where>标签

标签用于在动态SQL中自动处理WHERE子句的生成,简化多条件查询的开发。它能自动处理逻辑连接词(如AND、OR)以及去除多余的关键字,使得代码更加简洁和高效。

XML.java文件代码:

List<UserInfo> selectByWhere();

.xml文件代码

  <select id="selectByWandroidhere" resultType="com.sliqvers.model.UserInfo">
            select * from user_info
        <where>
            <if test="username!=null">
                and username=#{usChina编程ername}
            </if>
            <if test="password!=null">
                or password=#{password}
            </if>
        <if test="age!=null">
            and age=#{age}
        </if>
            <if test="phone!=null">
             or   phone=#{phone}
            </if>
        </where>
    </select>

测试类

  @Test
    void selectByWhere() {
        userInfoMapperXML.selectByWhere().stream().forEach(x-> System.out.println(x));
    }

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

生成的SQL:
当username和phonel都有值:
SELECT * FROM user_info WHERE username = ? AND phone =?;
当只有username有值:
SELECT * FROM user_info WHERE username =?;
当两者都为null:
SELECT * FROM user_info;

2.4<set>标签

标签在UPDATE语句中起到动态设置字段值的作用,自动处理SET关键字和逗号,避免空更新。通过合理使用<set>标签,可以简化代码,提高SQL执行效率,确保系统安全性和稳定性。

XML.java文件

 Integer upadteUserSql(UserInfo userInfo);

.xml文件

    <update id="upadteUserSql">
        update user_info
        <set>
            <if test="password!=null">
                password = #{password} ,
            </if>
            <if test="username!=null">
                username = #{username},
            </if>
        </set>
        where id=#{id}
    </update>

测试类:

    @Test
    void upadteUserSql() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("Sliqvers");
        userInfo.setPassword("111111");
        userInfo.setId(1);
        userInfoMapperXML.upadteUserSql(userInfo);
    }

运行结果:

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

生成的SQL:
当username和password都有值:
UPDATE user_info SET username = ?, email = ? WHERE id = ?
当只有username有值:
UPDATE user_info SET username = ? WHERE id = ?
当只有password有值:
UPDATE users_info SET password = ? WHERE id = ?
当两者都为null:
UPDATE user_info WHERE id = ?

2.5 <foreach> 标签

<foreach>标签在动态SQL中起到遍历集合或数组的作用,生成IN子句、批量INSERT或UPDATE等操作。通过合理使用标签,可以简化批量操作的SQL拼接,提高开发效率和系统性能。同时,注意避免SQL注入和空集合处理等问题,可确保动态SQL的安全性和可靠性。

<foreach> 标签的属性

collection:必填,指定要遍历的集合名。
item:必填,指定遍历时的变量名。
open:可选,遍历开始时添加的字符串。
close:可选,遍历结束时添加的字符串。
separator:可选,遍历时的分隔符(默认",")。
index:可选,遍历时的索引变量。
select:可选,用于嵌套查询。

XML.java接口

  List<UserInfo> selectBySql(List<Integer> ids);

.xml文件

    <select id="selectBySql" resultType="com.sliqvers.model.UserInfo">
        select * from user_info where id in
        <foreach collection="ids" open="(" close=")" separator="," item="id">
            #{id}
        </foreach>
    </select>

测试类

    @Test
    void selectBySql() {
        List<Integer> ids=new ArrayList<>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        userInfoMapperXML.selectBySql(ids).stream().forEach(x-> System.out.println(x));
    }

运行结果:

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

生成的SQL:
ids = [1, 2, 3] 时:
SELECT * FROM user_info WHERE id IN (1, 2, 3)

2.6 <include>标签

在xml映射⽂件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码,我们可以对重复的代码片段进行抽取,将其通过 <sql> 标签封装到⼀个SQL片段,然后再通过<include> 标签进行引用。

定义一个常用的WHERE条件

<sql id="allColumn">
 id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>

通过 <include> 标签在原来抽取的地方进行引用。操作如下:

<select id="queryAllUser" resultMap="BaseMap">
 select
 <include refid="allColumn"></include>
 from user_info
</select>

三、动态SQL的注意事项

3.1 China编程SQL注入问题(搞破坏)

  • 风险:直接拼接用户输入可能导致SQL注入。
  • 解决方案:使用参数化查询或ORM框架(如MyBatis)提供的安全功能。

3.2 performance

  • 执行计划缓存:动态SQL可能导致数据库无法有效利用执行计划缓存。
  • 优化建议:尽量减少动态SQL的使用场景,或者使用有限的条件组合。

3.3 动态SQL的可读性和维护性

  • 复杂性:动态SQL可能使代码更难阅读和维护。
  • 建议:合理分层代码,遵循编码规范。

四、总结

本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化 MyBatis 配置,提升开发效率,确保 SQL 的高效执行和安全性。学习这些技巧,帮助开发者更高效地构建和维护数据库交互层。

到此这篇关于MyBatis 动态 SQL 优化:标签的实战与技巧的文章就介绍到这了,更多相关MyBatis 动态 SQL 内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154067

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

JDK21对虚拟线程的几种用法实践指南

《JDK21对虚拟线程的几种用法实践指南》虚拟线程是Java中的一种轻量级线程,由JVM管理,特别适合于I/O密集型任务,:本文主要介绍JDK21对虚拟线程的几种用法,文中通过代码介绍的非常详细,... 目录一、参考官方文档二、什么是虚拟线程三、几种用法1、Thread.ofVirtual().start(

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

mysql8.0.43使用InnoDB Cluster配置主从复制

《mysql8.0.43使用InnoDBCluster配置主从复制》本文主要介绍了mysql8.0.43使用InnoDBCluster配置主从复制,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录1、配置Hosts解析(所有服务器都要执行)2、安装mysql shell(所有服务器都要执行)3、

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S

k8s中实现mysql主备过程详解

《k8s中实现mysql主备过程详解》文章讲解了在K8s中使用StatefulSet部署MySQL主备架构,包含NFS安装、storageClass配置、MySQL部署及同步检查步骤,确保主备数据一致... 目录一、k8s中实现mysql主备1.1 环境信息1.2 部署nfs-provisioner1.2.

MySQL中VARCHAR和TEXT的区别小结

《MySQL中VARCHAR和TEXT的区别小结》MySQL中VARCHAR和TEXT用于存储字符串,VARCHAR可变长度存储在行内,适合短文本;TEXT存储在溢出页,适合大文本,下面就来具体的了解... 目录一、VARCHAR 和 TEXT 基本介绍1. VARCHAR2. TEXT二、VARCHAR