河南中恒诚信建设有限公司网站,慈城旅游网站建设策划书,电商网站开发的流程图,做网站程序员系列文章目录
MyBatis缓存原理 Mybatis的CachingExecutor与二级缓存 Mybatis plugin 的使用及原理 MyBatis四大组件Executor、StatementHandler、ParameterHandler、ResultSetHandler 详解 MyBatisSpringboot 启动到SQL执行全流程 数据库操作不再困难#xff0c;MyBatis动态S…系列文章目录
MyBatis缓存原理 Mybatis的CachingExecutor与二级缓存 Mybatis plugin 的使用及原理 MyBatis四大组件Executor、StatementHandler、ParameterHandler、ResultSetHandler 详解 MyBatisSpringboot 启动到SQL执行全流程 数据库操作不再困难MyBatis动态Sql标签解析 系列文章目录一、动态sql是什么二、动态sql原理三、动态标签解释1. if 标签2 choose、when 和 otherwise 标签3 trim 标签4 foreach 标签遍历集合遍历数组遍历Map 5 set 标签6 bind 标签7 sql 与 include 标签8. where 标签 总结 使用MyBatis或者MyBatis-plus有一项重要的开发技能就是写动态sql动态sql能帮我们省略很多复杂逻辑也能帮我们解决一些格式问题所以今天我们就来帮大家掌握这个动态sql 作者简介战斧从事金融IT行业有着多年一线开发、架构经验爱好广泛乐于分享致力于创作更多高质量内容 本文收录于 MyBatis专栏 有需要者可直接订阅专栏实时获取更新 高质量专栏 云原生、RabbitMQ、Spring全家桶 等仍在更新欢迎指导 Zookeeper Redis kafka docker netty等诸多框架以及架构与分布式专题即将上线敬请期待 一、动态sql是什么 假设有一个电商网站需要根据用户提供的不同条件查询商品信息比如说价格、商品名、类别等等我们需要写出每个查询信息对应的SQL语句例如 SELECT * FROM Product WHERE price #{price}; SELECT * FROM Product WHERE productname #{name} SELECT * FROM Product WHERE type #{type}; … 如果这样各种各样的筛选逻辑很多我们就需要写很多条类似的SQL语句而且还需要判断入参是否合理是否为空等等。这样我们的sql就会非常的难以维护。此时我们就需要利用到MyBatis的动态SQL。
MyBatis的动态SQL是指在SQL语句中可以根据不同的条件动态生成不同的SQL语句以适应不同的需求。动态SQL可以根据条件生成不同的SQL语句比如WHERE条件、ORDER BY、动态判断等等从而实现更灵活的SQL编写。动态SQL的主要作用是让SQL语句更加灵活、可重用和易维护提高应用程序的灵活性和可扩展性
二、动态sql原理
MyBatis动态sql标签的实现原理主要是通过OGNL表达式和Java反射机制来实现的。
首先MyBatis会将动态sql标签中的OGNL表达式解析成Java代码。解析过程中MyBatis会根据OGNL表达式的类型来生成相应的Java代码片段。例如当解析if标签时如果判断条件中的OGNL表达式为布尔类型则会生成一个if语句的Java代码片段。
其次MyBatis会使用Java反射机制获取实体类的属性值并将属性值传递给动态sql标签中的OGNL表达式进行判断。如果判断条件满足则会将动态sql标签中的内容添加到SQL语句中反之则会忽略动态sql标签中的内容。
总体来讲MyBatis动态sql标签的实现原理就是将OGNL表达式解析成Java代码并使用Java反射机制获取实体类属性值进行判断以实现SQL语句的动态生成。myBtais整体运行流程可以看往期的 MyBatisSpringboot 启动到SQL执行全流程
三、动态标签解释
1. if 标签
if标签允许你根据条件判断是否包含特定的SQL片段用于构建灵活的查询语句该标签的使用方法如下
在需要动态生成条件的SQL语句中使用if标签。在if标签中添加一个test属性用于指定一个boolean表达式这个表达式会决定是否将当前条件语句包含在生成的SQL语句中。在if 至 /if标签中设置需要动态生成的条件语句。
select idgetUser resultMapuserResultMapSELECT * FROM userwhere 1 1if testname ! nullAND name #{name}/ifif testage ! nullAND age #{age}/if
/select在这个示例中if标签用于根据条件动态生成SQL语句中的条件语句。如果传递到这个方法的参数中包含一个非空的name属性那么就会在SQL语句中添加一个“name #{name}”的条件语句如果包含一个非空的age属性那么就会在SQL语句中添加一个“age #{age}”的条件语句。
需要注意的是使用标签时必须要用“AND”或“OR”将多个if标签组合在一起否则会出现语法错误。此外还需要注意在使用标签时SQL语句的正确性和性能的折中。太多的动态条件可能会导致SQL语句生成的复杂度增加从而影响查询的性能
2 choose、when 和 otherwise 标签
choose、when和otherwise标签通常一起使用来实现条件分支查询。这种方式类似于Java中的switch语句或者if-else语句
其中choose标签类似于Java中的switch语句表示一个选择分支包含多个when和otherwise标签。when标签类似于Java中的case语句用于指定分支条件。当条件满足时执行when标签内的SQL语句。otherwise标签类似于Java中的default语句用于指定默认条件分支。当其他分支条件都不满足时执行otherwise标签内的SQL语句。
select idgetUsersByAgeAndName parameterTypemap resultMapuserMapSELECT * FROM userswherechoosewhen testage ! null and name ! nullage #{age} AND name #{name}/whenwhen testage ! nullage #{age}/whenwhen testname ! nullname #{name}/whenotherwise11/otherwise/choose/where
/select
如上我们使用choose、when和otherwise标签来实现条件分支查询。这个查询可以根据参数中的年龄和名字来查找用户记录也可以只根据年龄或者名字来查找或者不加任何条件查询所有的用户记录
3 trim 标签
trim标签用于修剪生成的SQL语句可以用于移除不必要的关键字特别是在拼接多个条件时非常有用其主要是用于确定子句中的前缀与后缀。
trim 标签具有以下属性 prefixOverrides要删除的前缀字符串可以以“|”分割添加多个词 suffixOverrides要删除的后缀字符串可以以“|”分割添加多个词 prefix要添加到 SQL 语句的前缀字符串 suffix要添加到 SQL 语句的后缀字符串
select idfindUserByName parameterTypejava.lang.String resultTypeUserSELECT * FROM usertrim prefixWHERE prefixOverridesOR | AND if testname ! null and name ! AND name #{name}/ifif testage ! nullAND age #{age}/if/trim
/select
在这个示例中 trim 标签用于动态构建 WHERE 子句。如果它会删除前缀中的 OR 或 AND 关键字并将 WHERE 关键字添加到 SQL 语句中。
当然你也许会想如果我把 prefixOverrides 和 prefix 是设置成一个词那这个词还会不会插入到子句句首呢答案是会的因为这里的逻辑是先删除prefixOverrides指定字符串再添加prefix指定字符串
4 foreach 标签
标签用于循环处理集合类型的参数生成多次重复的SQL片段该标签可以用于循环遍历一个集合或数组并在SQL语句中使用它的值。以下是标签的使用方法。
遍历集合
select idfindUserById parameterTypejava.lang.IntegerSELECT * FROM table WHERE id INforeach collectionlist itemitem open( separator, close)#{item}/foreach
/select其中collection属性指定要遍历的集合item属性指定集合中每个元素的别名open属性指定在开始时添加的字符串separator属性指定在每个元素之间添加的字符串close属性指定在结束时添加的字符串。
例如如果list是一个包含1、2、3的List对象这个标签会生成以下SQL语句
SELECT * FROM table WHERE id IN (1,2,3)遍历数组
foreach collectionarray itemitem open( separator, close)#{item}
/foreach这个标签与遍历集合的标签非常相似只不过把collection属性改为了数组对象
遍历Map
假设我们有这样一个map
MapString, Object searchCriteria new HashMap();
searchCriteria.put(username, john);
searchCriteria.put(age, 25);
searchCriteria.put(city, New York);然后我们配上这样的xml
select idsearchUsers parameterTypemap resultTypeUserSELECT * FROM userforeach collectionsearchCriteria itemvalue indexkey separatorAND openWHERE${key} #{value}/foreach
/select
其中collection属性指定要遍历的Map集合index属性指定键的别名item属性指定值的别名open属性指定在开始时添加的字符串separator属性指定在每个元素之间添加的字符串。
最后我们能得到这样的sql
SELECT * FROM user WHERE username john AND age 25 AND city New York5 set 标签
标签通常用于动态生成UPDATE语句的SET部分可自动生成逗号分隔的键值对set标签通常包含多个标签或者标签用于动态生成要更新的列和值。 UPDATE usersetif testusername ! nullusername #{username},/ifif testpassword ! nullpassword #{password},/ifif testemail ! nullemail #{email},/if/setWHERE id #{id}
/update
在这个示例中标签根据传入的参数动态生成SET部分。set 元素会动态地在行首插入 SET 关键字并会删掉额外的逗号
6 bind 标签
bind用于将一个表达式绑定到一个变量上。绑定的变量可以在后面的SQL语句中引用。通常标签被用于简化SQL语句中的重复表达式提高SQL语句的可读性和可维护性。
select idfindUsers parameterTypeString resultMapuserResultMapbind namepattern value% name %/SELECT * FROM user WHERE name LIKE #{pattern}
/select在上面的例子中标签用于将一个字符串表达式绑定到名为pattern的变量上。变量的值是一个由‘%’‘name’和‘%’组成的字符串其中‘name’是一个参数。在后面的SQL语句中#{pattern}即可引用绑定的变量。
在标签中name属性指定变量的名称value属性指定变量的值。可以在value属性中使用表达式变量名和参数Map中的键。
除了绑定表达式到变量上标签还可以用于绑定参数值到变量上。例如
select idfindUsersByAge parameterTypeint resultMapuserResultMapbind nameminAge valueage - 5/bind namemaxAge valueage 5/SELECT * FROM user WHERE age BETWEEN #{minAge} AND #{maxAge}
/select在上面的例子中bind标签用于将一个整数参数值绑定到名为minAge和maxAge的变量上。变量的值是通过计算参数值得到的。在后面的SQL语句中#{minAge}和#{maxAge}即可引用绑定的变量。
总之bind标签是一个非常强大的MyBatis功能可以提高SQL语句的可读性和可维护性。在开发MyBatis应用程序时应该灵活使用标签以便更好地管理SQL语句。
7 sql 与 include 标签
sql标签用于定义可重用的SQL片段。在一个或多个SQL语句中可以使用标签来引用这些SQL片段。 sql iduserColumnsid, username, age
/sqlselect idgetAllUsers resultTypeUserSELECT include refiduserColumns /FROM user
/selectselect idgetUsersByName parameterTypeString resultTypeUserSELECT include refiduserColumns /FROM userWHERENAME #{name}
/select上述例子中include标签引用了一个名为userColumns的SQL片段。引用的方式是通过refid属性指定片段的ID。所有引用的SQL片段都会被添加到原始SQL语句中。这样其他sql如果也是使用这几个字段则都可以引用
8. where 标签
where 标签的作用是用来包裹一个或多个 SQL 条件语句如果这些条件都满足则会被加入到 SELECT 或 UPDATE 语句中否则不会。它的使用方法如下
1.将多个条件语句用 标签包裹起来。
select idselectByCondition parameterTypejava.util.Map resultMapuserMapselect * from userwhereif testname ! null and name!and name like CONCAT(%,#{name},%)/ifif testage ! nulland age #{age}/if/where
/select2.在 SQL 语句中使用 where 标签时会自动移除掉多余的 AND 或 OR而在没有任何条件语句时where 标签也会自动删除自身以避免 SQL 语法错误。例如上述代码在没有任何条件时生成的 SQL 语句为
select * from user而当输入 age20 时生成的 SQL 语句为:
select * from userwhere age 20可以看出where 标签是 MyBatis 中一个非常有用的标签它可以帮助我们更加方便地动态构建 SQL 语句提高代码的可读性和可维护性。 总结
MyBatis的动态SQL功能极大地简化了数据库操作使得针对不同查询需求的SQL语句生成变得灵活而高效。通过深入了解和掌握if、choose、when、otherwise、trim、foreach、set、bind和sql等核心标签开发人员将大幅度减少因为参数不同而写不同sql的麻烦此时的sql会自己按预设逻辑变成不同的样式。因此需要牢牢掌握。