Spring Boot MyBatis升级篇-注解-动态SQL(if test)-方案二:@Provider(8)
1)动态语言注解
(2)@Provider使用思路
(3)@SelectProvider小试牛刀
(4)@SelectProvider初露锋芒
(5)@SelectProvider过关斩将
(6)@InsertProvider小弟不敢当
(7)@UpdateProvider你加我来改
(8)@DeleteProvider不高兴就删
接下来看下具体的内容:
(1)动态语言注解
对于创建动态的查的语言。MyBatis提供了多个注解如:@InsertProvider,@UpdateProvider,@DeleteProvider和@SelectProvider,这些都是建立动态语言和让MyBatis执行这些语言。
(2)@Provider使用思路
对于MyBatis提供的几个@Provider,里面最主要的参数是type,也就是sql类的Calss对象,另外就是对应的方法名,我们看SelectProvider的源代码:
Java代码 收藏代码 @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SelectProvider { Class<?> type(); String method(); }
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SelectProvider { Class<?> type(); String method(); }
所以要实现动态的SQL查询,那么大体的思路就是,编写一个SqlProvider,比如:DemoSqlProvider,在此方法中返回一条SQL语句即可。然后在Mapper类中使用@SelectProvider注解,指定provider类和对应的SQL方法。
接下来我们来解决上一篇博客的问题:
问题:有一个表中有id,name,email等字段,有这么一个查询要求:我们希望的是如果name不为null的话,那么就当做条件,否则就不要当做条件;如果email不为null,那么就当做条件,否则不当做条件。
接下里看看怎么使用@SelectProvider破。
(3)@SelectProvider小试牛刀
我们先编写一个DemoSqlProvider,代码如下:
package com.kfit.demo.mapper; import com.kfit.demo.bean.Demo; public class DemoSqlProvider { /** * 查询语句. * @param demo * @return */ public String select5(Demo demo){ StringBuffer sql = new StringBuffer("select *from demo where 1=1 "); if(demo.getName() != null){ sql.append(" and name=#{name}"); } if(demo.getEmail() != null){ sql.append(" and email=#{email}"); } return sql.toString(); } }
package com.kfit.demo.mapper; import com.kfit.demo.bean.Demo; public class DemoSqlProvider { /** * 查询语句. * @param demo * @return */ public String select5(Demo demo){ StringBuffer sql = new StringBuffer("select *from demo where 1=1 "); if(demo.getName() != null){ sql.append(" and name=#{name}"); } if(demo.getEmail() != null){ sql.append(" and email=#{email}"); } return sql.toString(); } }
在DemoMapper中加入查询方法:
@SelectProvider(type=DemoSqlProvider.class,method="select5") public List<Demo> select5(Demo demo);
@SelectProvider(type=DemoSqlProvider.class,method="select5") public List<Demo> select5(Demo demo);
这里使用@SelectProvider,不是@Select了。
访问1:http://127.0.0.1:8080/select4会返回全部数据,动态SQL是:
SELECT * from Demo WHERE 1=1
- SELECT * from Demo WHERE 1=1
访问2:http://127.0.0.1:8080/select4?name=王五会返回name=王五的数据,动态SQL是:
- SELECT * from Demo WHERE 1=1 and name=?
- SELECT * from Demo WHERE 1=1 and name=?
访问3:http://127.0.0.1:8080/select4?name=王五&email=aa@qq.com会返回name=王五并且email=aa@qq.com的数据,动态SQL是:
- SELECT * from Demo WHERE 1=1 and name=? and email=?
- SELECT * from Demo WHERE 1=1 and name=? and email=?
(4)@SelectProvider初露锋芒
上面的代码直接纯SQL编写了,可读性还是相对差了点,MyBatis提供了SQL类(org.apache.ibatis.jdbc.SQL),可以让代码看起来更有意义。
在DemoSqlProvider中加入方法:
/** * 查询语句.使用SQL * @param demo * @return */ public String select6(final Demo demo){ return new SQL(){{ SELECT("id,name,email"); FROM("demo"); if(demo.getName() != null){ WHERE("name=#{name}"); } if(demo.getEmail() != null){ WHERE("email=#{email}"); } }}.toString(); }
在DempMapper中加入代码:
@SelectProvider(type=DemoSqlProvider.class,method="select6") public List<Demo> select6(Demo demo);
(5)@SelectProvider过关斩将
原以为万事大吉了,开心的不行,于是乎,信手拈来句代码,在查询代码加入:
PageHelper.startPage(1, 2);整个代码如下:
@RequestMapping("/select6") public List<Demo> select6(Demo demo){ PageHelper.startPage(1, 2); return demoService.select6(demo); }
@RequestMapping("/select6") public List<Demo> select6(Demo demo){ PageHelper.startPage(1, 2); return demoService.select6(demo); }
运行,访问:http://127.0.0.1:8080/select6完了,这是什么鬼: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'providerTakesParameterObject' in 'class org.apache.ibatis.builder.annotation.ProviderSqlSource' 出现以上问题,是由于我们使用的PageHelper版本导致的,升级版本即可。
运行,访问:http://127.0.0.1:8080/select6完了,这是什么鬼:
nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'providerTakesParameterObject' in 'class org.apache.ibatis.builder.annotation.ProviderSqlSource'
出现以上问题,是由于我们使用的PageHelper版本导致的,升级版本即可。
原先的版本为:
Xml代码 收藏代码 <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.0</version> </dependency> [xml] view plain copy
升级为:
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.2.1</version> </dependency>
貌似:4.1.5就支持@SelectProvider分页查询了(未进行验证)。
(6)@InsertProvider小弟不敢当
最麻烦的查询搞定了之后,这个就简单了,
在DemoSqlProvider中加入如下代码:
/** * 查询语句.使用SQL * @param demo * @return */ public String save3(final Demo demo){ return new SQL(){{ INSERT_INTO("demo"); //多个写法. INTO_COLUMNS("name","email"); INTO_VALUES("#{name}","#{email}"); //条件写法. // if(demo.getName() != null){ // VALUES("name","#{name}"); // } // if(demo.getEmail() != null){ // VALUES("email","#{email}"); // } }}.toString(); }
在DemoMapper中加入如下代码:
ava代码 收藏代码 @InsertProvider(type=DemoSqlProvider.class,method="save3") @Options(keyProperty="id",keyColumn="id",useGeneratedKeys=true) public void save3(Demo demo);
(7)@UpdateProvider你加我来改
DemoSqlProvider中的代码如下:
Java代码 收藏代码 /** * @param demo * @return */ public String update2(final Demo demo){ return new SQL(){{ UPDATE("demo"); //条件写法. if(demo.getName() != null){ SET("name=#{name}"); } if(demo.getEmail() != null){ SET("email=#{email}"); } WHERE("id=#{id}"); }}.toString(); }
在DemoMapper中的代码:
码 收藏代码 @UpdateProvider(type=DemoSqlProvider.class,method="update2") public int update2(Demo demo);
(8)@DeleteProvider不高兴就删
DemoSqlProvider代码:
Java代码 收藏代码 /** * @param demo * @return */ public String delete2(){ return new SQL(){{ DELETE_FROM("demo"); WHERE("id=#{id}"); }}.toString(); }
在DemoMapper中的代码:
@UpdateProvider(type=DemoSqlProvider.class,method="delete2") public int delete2(int id);
相关文章
- Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part B MyBatis)
- Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part D MyBatis Plus)
- Spring Boot – Mybatis 缓存
- spring注解有哪些_Spring 注解
- Spring Cloud:第三章:Ribbon客服端负载均衡
- 面试题springboot启动流程_Spring boot面试
- spring boot整合shiro_Spring框架介绍及使用
- 为什么说 Java 程序员到了必须掌握 Spring Boot 的时候?
- 学习Spring Boot前送你3个锦囊
- Spring Boot整合Mybatis Plus[极简教程]
- springboot 集成mybatis-plus_Spring Boot
- Spring Boot 整合定时任务,可以动态编辑的定时任务
- Spring Boot Starters介绍[通俗易懂]
- Spring Boot下如何使用自定义的测试切片
- Spring Boot整合MyBatis(保姆级教程)
- SpringBoot基础学习文章-Java环境变量配置Maven介绍Spring Boot介绍
- Spring Boot + LayUi登陆遇到问题记录
- SpringBoot:模块探究之spring-boot-dependencies
- Spring Boot集成Disruptor
- Spring Boot的依赖管理和构建工具
- Spring Cloud Security进行安全审计(一)
- Spring MVC @ModelAttribute注解
- Spring 官网下载zip jar详解编程语言
- Spring Cloud(一):概述以及核心成员介绍详解编程语言
- Spring Boot实现热部署详解编程语言
- Spring Boot 2.x 启动全过程源码分析(上)入口类剖析详解编程语言
- spring Boot(十九):使用Spring Boot Actuator监控应用详解编程语言
- 使用Spring boot 嵌入的tomcat不能启动: Unregistering JMX-exposed beans on shutdown详解编程语言
- java 线程池 spring线程池 多线程知识总结详解编程语言