网站自建,百度账号申诉,绍兴网站建设电话,网站维护 一年专栏精选
引入Mybatis
Mybatis的快速入门
Mybatis的增删改查扩展功能说明
mapper映射的参数和结果
Mybatis复杂类型的结果映射
Mybatis基于注解的结果映射
Mybatis枚举类型处理和类型处理器
再谈动态SQL
Mybatis配置入门
Mybatis行为配置之Ⅰ—缓存
Mybatis行为配置…专栏精选
引入Mybatis
Mybatis的快速入门
Mybatis的增删改查扩展功能说明
mapper映射的参数和结果
Mybatis复杂类型的结果映射
Mybatis基于注解的结果映射
Mybatis枚举类型处理和类型处理器
再谈动态SQL
Mybatis配置入门
Mybatis行为配置之Ⅰ—缓存
Mybatis行为配置之Ⅱ—结果相关配置项说明
Mybatis行为配置之Ⅲ—其他行为配置项说明
Mybatis行为配置之Ⅳ—日志
Mybatis整合Spring详解
Mybatis插件入门
Mybatis专栏代码资源 文章目录 专栏精选摘要引言正文动态sql标签ifchoose...when...otherwisewhere、settrimforeachscript 动态sql API通过类名和方法名定位SQL通过方法名定位SQL自动定位SQL 总结 摘要
在这篇文章中我们将深入Mybatis动态SQL的世界了解动态SQL标签和动态sqlAPI的基本方法其中的很多观点或内容都能在一定程度上让我们的开发之旅更加轻松方便这是一个菜鸟提升技术能力老鸟巩固基础知识的好机会。准备好开启今天的神奇之旅了吗
引言
大家好我是奇迹老李一个专注于分享开发经验和基础教程的博主。欢迎来到我的频道这里汇聚了汇集编程技巧、代码示例和技术教程欢迎广大朋友们点赞评论提出意见重要的是点击关注喔 期待在这里与你共同度过美好的时光️今天要和大家分享的内容是再谈动态SQL。做好准备Let’s go
正文 在引入Mybatis一文中我们提到jdbc对于过长过复杂多条件查询的无力感Mybatis提供动态SQL这一特性解决拼接SQL语句的痛点。在之前的文章中我们已经简单介绍过动态SQL的一些特性如
条件语句if、choose…when…otherwise循环语句foreachsql条件语句where、set
除此之外动态SQL还包含以下几种特性 扩展语句trim、bind、script 动态sql API
动态sql标签
if
if testnull ! appName and .toString() ! appNameand app_name like concat(%,#{appName},%)/if
if testnull ! authType and .toString() ! authTypeand auth_type #{authType}/if
if testnull ! startDate and ! startDateand create_date #{startDate}/if
if testnull ! endDate and ! endDateand create_date lt; #{endDate}/ifchoose…when…otherwise
mybatis映射文件中的 if…else
choose when testid ! null and id 0id#{id}/when when testid 0is_del0/whenotherwiseid1/otherwise
/choosejava代码的同义改写
Intege id...;
if(id ! null id 0){//id#{id}
}else if(id 0){//is_del0
}else{//id1
}where、set where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且若子句的开头为 “AND” 或 “OR”where 元素也会将它们去除。 —— Mybatis官方文档 !--如果满足if条件and auth_type #{authType}中的“and ”将会被删除并在前边添加“where ”其结果是--
!--where auth_type #{authType}--
select * from app_test
where if testnull ! authType and .toString() ! authTypeand auth_type #{authType}/if
/whereset 元素用于更新update语句中的set部分和where一样set的子元素返回的结果结尾如果有“, ”set元素也会自动将其去除 !--如果满足if条件app_name #{appName},中的“,”会被删除其他的“,”不会删除并在语句之前添加“set ”其结果是--
!--update app_test set app_code #{appCode},app_name #{appName} where id#{id}--
update app_test
set if testappCode ! null and ! appCodeapp_code #{appCode},/ifif testappName ! null and ! appNameapp_name #{appName},/if
/set
where id#{id}trim trim元素中可以自定义子句应该忽略的内容、和应该添加的内容where和set标签的功能都能通过trim实现 trim实现where的功能
!--prefix属性表示将要给子句添加的前缀prefixOverrides属性表示子句如果出现这样的开头将其忽略--
select * from app_test
trim prefixWHERE prefixOverridesAND |OR if testnull ! authType and .toString() ! authTypeAND auth_type #{authType}/if
/trimtrim实现set的功能
!--suffixOverrides属性表示子句如果出现这样的结尾将其忽略--
update app_test
trim prefixSET suffixOverrides,if testappCode ! null and ! appCodeapp_code #{appCode},/ifif testappName ! null and ! appNameapp_name #{appName},/if
/trim
where id#{id}trim标签属性详解
序号属性名效果说明1prefix前缀2suffix后缀3prefixOverrides将被删除的前缀4suffixOverrides将被删除的后缀
由此可见以上的set内容可以写成如下形式
update upp_test set
trim suffixwhere id#{id} suffixOverrides,if testappCode ! null and ! appCodeapp_code #{appCode},/ifif testappName ! null and ! appNameapp_name #{appName},/if
/trim相应的where内容也可以写成如下形式
select * from app_test
trim prefixwhere prefixOverridesAND |OR if testnull ! authType and .toString() ! authTypeAND auth_type #{authType}/if
/trimforeach foreach标签用来遍历集合数据 foreach标签的使用方式如下
insert into app_test(app_name,app_code,auth_type,create_date,creator) values
foreach collectionlist separator, itementity indexindex open close (#{entity.appName},#{entity.appCode},#{entity.authType},#{entity.createDate},#{entity.creator})
/foreachforeach标签的属性说明
序号属性名属性说明1collection集合数据的参数名称2index集合数据的索引方式一般默认为index3item集合内部的元素命名类似for(T t,ListT)中的t4open左侧需要添加的字符5close右侧需要添加的字符
script
Mybatis支持通过注解的形式编写sql语句主要通过Select,Insert,Update,Delete几个注解实现示例如下
Select(select * from app_test where auth_type#{type})
ListAppTestEntity queryList(Param(type) String type);这样就省略了创建xml映射文件的工作但是这样有一个缺点就是不方便编写动态sql这时可以使用script标签
public interface ApplicationRepository {Update({ script, update app_test, set, if test\appStatus ! null and appStatus ! \app_status#{appStatus},/if, /set, where id#{id}, /script }) int updateByScript(AppTestEntity app);
}这里需要注意在字符串中使用 双引号字符需要使用 \ 符号转义如上例所示
动态sql API
除了通过映射文件使用动态sql的方式之外Mybatis还提供了基于JavaAPI实现动态sql的方案。(这种方法可以弥补script标签的不足)
通过类名和方法名定位SQL
这里我们针对AppTest对象的条件查询进行改造
public interface ApplicationRepository {//此注解用于标注动态sql生成的类方法名称SelectProvider(type ApplicationSqlProvider.class,method queryAppFunc) ListAppTestEntity queryAppProvider(AppSearchVo param);
}//动态sql生成类
//这个类名称和方法名称需要和SelectProvider注解标注的类型和方法名称相对应
package top.sunyog.mybatis.provider; import org.apache.ibatis.jdbc.SQL;
import top.sunyog.common.entity.AppSearchVo; public class ApplicationSqlProvider { public static String queryAppFunc(AppSearchVo param){ SQL sql new SQL() {//静态代码块{ SELECT(*); FROM(app_test); if (param.getAppName()!null !.equals(param.getAppName())) { WHERE(app_name like concat(%,#{appName},%)); } if (param.getAuthType()!null !.equals(param.getAuthType())){ WHERE(auth_type #{authType}); } if (param.getStartDate() ! null){ WHERE(create_date #{startDate}); } if (param.getEndDate() ! null){ WHERE(create_date #{endDate}); } }}; return sql.toString(); }
}
功能测试类
public class ApplicationService extends MybatisServiceApplicationRepository{Override public void doService() { ApplicationRepository mapper super.getMapper(ApplicationRepository.class); this.testSelectProvider(mapper); }private void testSelectProvider(ApplicationRepository mapper){ AppSearchVo vo new AppSearchVo(); vo.setAppName(1); vo.setAuthType(2); vo.setStartDate(LocalDateTime.of(2023,11,1,12,10)); vo.setEndDate(LocalDateTime.of(2023,11,3,12,10)); ListAppTestEntity list mapper.queryAppProvider(vo); list.forEach(System.out::println); }
}通过方法名定位SQL
除了通过 SelectProvider注解直接指定类和方法之外还可以只指定类但这种方式需要保证Mapper接口的方法名称和 Provider类的方法名称一一对应。
//mapper接口
SelectProvider(type ApplicationSqlProvider.class)
ListAppTestEntity queryAppProvider(AppSearchVo param);//provider类
public class ApplicationSqlProvider implements ProviderMethodResolver { public static String queryAppProvider(AppSearchVo param){...}
}使用这种方式需要保证两点
方法名称相同provider类实现 ProviderMethodResolver 接口
自动定位SQL
通过配置默认的 SqlProvider类可以将所有的 *Provider 定位到同一个类中只要保证 mapper接口的方法名称和 Provider类的方法名称相同即可
配置说明
configuration properties resource.../settings !--设定默认的 sql provider--setting namedefaultSqlProviderType valuetop.sunyog.mybatis.provider.ApplicationSqlProvider/ /settings...
/configurationmapper接口和provider类
//mapper接口
SelectProvider
ListAppTestEntity queryAppProvider(AppSearchVo param);//provider类
public class ApplicationSqlProvider implements ProviderMethodResolver { public static String queryAppProvider(AppSearchVo param){...}
}总结
在MyBatis中动态SQL是非常有用的特性它们允许开发者根据不同的条件构建动态的SQL查询以及更加灵活地生成SQL查询。动态SQL标签提供了灵活的逻辑控制使我们可以根据不同的条件动态地添加或删除SQL片段。动态SQL API允许我们以编码的方式使用动态SQL这就相当于在动态SQL之上引入了更加灵活的逻辑处理功能。
你是否曾经使用过MyBatis的动态SQL标签或相关API如果有请在评论区分享你的使用经验和心得。如果你还没有使用过这些特性现在可以用起来了。 联系方式 邮箱qijilaolifoxmail.com ❗版权声明 本文为原创文章版权归作者所有。未经许可禁止转载。更多内容请访问奇迹老李的博客首页