本文主要是介绍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方式)
数据库数据信息
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); }
运行结果:
可以看到把gender
这个字段使用if标签之后,这个字段就被移除了。
2.2< trim>标签
trim标签在动态SQL中起到格式化SQL语句的作用,允许开发者在生成SQL时自动处理空格、换行符以及前缀后缀的添加。通过合理使用trim标签,可以简化动态SQL的开发,提高代码的可读性和维护性,同时确保生成的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);
运行结果:
修改 .xml
文件,通过trim标签给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)); }
生成的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); }
运行结果:
生成的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)); }
运行结果:
生成的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 优化之标签的实战与技巧(常见用法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!