MyBatis
动态 SQL 标签
MyBatis 动态 SQL 标签,是一组预定义的标签,用于构建动态的 SQL 语句,允许在 SQL 语句中使用条件、循环和迭代等逻辑。通过使用动态 SQL 标签,开发者可以根据不同的条件和参数生成不同的 SQL 语句,实现更加灵活的数据访问操作。但是,需要谨慎处理 SQL 注入问题,确保所有的输入都经过正确的验证和转义处理,以防止安全漏洞的产生。
常用的动态 SQL 标签
- if 标签:根据条件判断是否包含 SQL 语句片段
- where 标签:根据条件控制 SQL 语句的查询条件部分
- trim 标签:根据条件去除或添加字符串前后的特定字符
- choose 、when 、otherwise 标签:根据条件选择不同的 SQL 语句片段
- foreach 标签:在 SQL 语句中迭代一个集合
简单示例:
首先,创建一张数据表 dynamic_sql_object
表结构如图:
表信息如图:
接着,创建与数据表一一映射的实体类 DynamicSqlObject
packagecn.edu.MyBatisDemo.model;publicclassDynamicSqlObject{privateint id;privateString name;privateString grade;privateint age;privateString phone;publicDynamicSqlObject(){super();}publicDynamicSqlObject(int id,String name,String grade,int age,String phone){this.id = id;this.name = name;this.grade = grade;this.age = age;this.phone = phone;}publicintgetId(){return id;}publicvoidsetId(int id){this.id = id;}publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}publicStringgetGrade(){return grade;}publicvoidsetGrade(String grade){this.grade = grade;}publicintgetAge(){return age;}publicvoidsetAge(int age){this.age = age;}publicStringgetPhone(){return phone;}publicvoidsetPhone(String phone){this.phone = phone;}@OverridepublicStringtoString(){return"DynamicSqlObject{"+"id="+ id +", name='"+ name +'\''+", grade='"+ grade +'\''+", age="+ age +", phone='"+ phone +'\''+'}';}}
然后,创建一个接口 DynamicSqlObjectMap ,声明获取指定用户信息的方法。同时,创建映射文件 DynamicSqlObjectMap.xml 实现接口方法
packagecn.edu.MyBatisDemo.mapper;importcn.edu.MyBatisDemo.model.DynamicSqlObject;importorg.apache.ibatis.annotations.Param;publicinterfaceDynamicSqlObjectMap{//加上 @Param() 注解防止抛出异常---ReflectionException: There is no getter for property named 'xxx'publicDynamicSqlObjectgetObject(@Param("name")String name,@Param("phone")String phone);// 获取指定用户信息}
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 每个标签示例中再补充 --><mappernamespace="cn.edu.MyBatisDemo.mapper.DynamicSqlObjectMap"><selectid="getObject"resultType="dynamicSqlObject">
SELECT `id`,`name`,`grade`,`age`,`phone` FROM `dynamic_sql_object`
</select></mapper>
最后,测试结果,对每个标签进行简单示例
if 标签
在上面的示例中,select 标签定义了一个名为 getObject 的查询语句,其结果类型为 DynamicSqlObject 。
在 SQL 语句中,首先可以使用 WHERE 1=1 来构建一个通用的条件,然后使用 if 标签根据不同的条件来添加额外的限制条件。在 if 标签中,使用 test 属性来判断条件是否满足,若满足则执行该标签内的 SQL 语句片段;若不满足则不执行。
结果如图:
传递的参数值为 {name: “曹操”, phone: null} ,则生成的 SQL 语句为
SELECT`id`,`name`,`grade`,`age`,`phone`FROM`dynamic_sql_object`WHERE1=1AND`name`='曹操'
where 标签
在 where 标签中,可以根据不同的条件动态生成不同的 WHERE 子句,从而灵活地执行数据库查询操作。在 where 标签内使用 if 标签来添加条件语句。
结果如图:
传递的参数值为 {name: “曹操”, phone: “13625987401”} ,则生成的 SQL 语句为
SELECT`id`,`name`,`grade`,`age`,`phone`FROM`dynamic_sql_object`WHERE`name`='曹操'AND`phone`='13625987401'
注:where 标签只可以去掉第一个条件语句中前面的 AND 或 OR
trim 标签
在 trim 标签中,可以在动态 SQL 语句中去除前缀或后缀,也可以在 select 、update 或 insert 标签中使用。
trim 标签属性
- prefix:添加前缀
- prefixOverrides:去除前缀
- suffix:添加后缀
- suffixOverrides:去除后缀
结果如图:
传递的参数值为 {name: “曹操”, phone: “13625987401”} ,则生成的 SQL 语句为
SELECT`id`,`name`,`grade`,`age`,`phone`FROM`dynamic_sql_object`WHERE`name`='曹操'AND`phone`='13625987401'
choose 、when 、otherwise 标签
choose、when、otherwise 标签是一组标签,配合使用。choose 标签包含多个 when 标签和一个 otherwise 标签。在 when 标签中,使用 test 属性来判断条件是否满足,若满足则执行该标签内的 SQL 语句片段;若没有任何条件满足,则 otherwise 标签内的 SQL 语句片段作为默认的语句片段执行。
结果如图:
传递的参数值为 {name: “曹操”, phone: “15489723601”} ,则生成的 SQL 语句为
SELECT`id`,`name`,`grade`,`age`,`phone`FROM`dynamic_sql_object`WHERE`name`='曹操'
注:
条件选择:在 when、otherwise 标签中,当多个条件都满足时,只选择最前面的一条 SQL 语句片段执行(从上往下的顺序)
条件判断:在 if 标签中,当多个条件都满足时,所有满足条件的 SQL 语句片段都会执行
foreach 标签
foreach 标签适用于遍历集合、批量操作的情况。
foreach 标签属性
- collection:指定的集合
- item:指定集合的每一个值的迭代变量
- separator:在生成的 SQL 语句中,每个元素之间的分隔符
- open:在生成的 SQL 语句中,需要在 IN 子句或 BETWEEN 子句的前面添加的字符串
- close:在生成的 SQL 语句中,需要在 IN 子句或 BETWEEN 子句的后面添加的字符串
foreach 标签示例中还需要再声明一个批量获取指定用户信息的方法。同时,在映射文件 DynamicSqlObjectMap.xml 中实现该接口方法
<selectid="getObjectByIds"resultType="dynamicSqlObject">
SELECT `id`,`name`,`grade`,`age`,`phone` FROM `dynamic_sql_object` WHERE `id` IN
<foreachcollection="ids"item="id"separator=","open="("close=")">
#{id}
</foreach></select>
结果如图:
传递的参数值为 {20230830,20230832} ,则生成的 SQL 语句为
SELECT`id`,`name`,`grade`,`age`,`phone`FROM`dynamic_sql_object`WHERE`id`IN(20230830,20230832)
附
set 标签用在更新的操作上,在 SQL 语句中动态生成多个 SET 子句。在 set 标签内使用多个 if 标签来判断哪些属性需要更新或不做处理。
sql 标签用于定义可重用的 SQL 片段,方便在不同的地方复用。include 标签用于将另一个映射文件中定义的 SQL 片段引入到当前映射文件中。这两个标签配合使用,可以减少重复的 SQL 代码,提高代码的可维护性和可读性。
bind 标签用于动态地生成 SQL 语句的绑定变量。
版权归原作者 啊Q老师 所有, 如有侵权,请联系我们删除。