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(, );
return demoService.select6(demo);
}
@RequestMapping("/select6")
public List<Demo> select6(Demo demo){
PageHelper.startPage(, );
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.</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 Boot MyBatis升级篇-注解-动态SQL(if test)-方案二:@Provider(8)的更多相关文章
- 54. spring boot日志升级篇—logback【从零开始学Spring Boot】
在<44. Spring Boot日志记录SLF4J>章节中有关相关的介绍,这里我们在深入的了解下logback框架. 为什么要使用logback ? --在开发中不建议使用System. ...
- 52. spring boot日志升级篇—log4j多环境不同日志级别的控制【从零开始学Spring Boot】
在上一章节中我们介绍了,仅通过log4j-spring.properties对日志级别进行控制,对于需要多环境部署的环境不是很方便,可能我们在开发环境大部分模块需要采用DEBUG级别,在测试环境可能需 ...
- 50. Spring Boot日志升级篇—log4j【从零开始学Spring Boot】
如果你使用的是spring boot 1.4.0版本的话,那么你可能需要配合以下文章进行学习 90.Spring Boot 1.4 使用log4j错误[从零开始学Spring Boot] Log4j是 ...
- Spring boot Mybatis 整合(注解版)
之前写过一篇关于springboot 与 mybatis整合的博文,使用了一段时间spring-data-jpa,发现那种方式真的是太爽了,mybatis的xml的映射配置总觉得有点麻烦.接口定义和映 ...
- 持久层之 MyBatis: 第二篇 :动态SQL And多表查询
MyBatis入门到精通 完整CRUD UserDaoImpl 编写UserDao对应的UserDaoMapper.xml 添加UserDao的测试用例 编写UserDao的测试用例 解决数据库字段名 ...
- 49. spring boot日志升级篇—理论【从零开始学Spring Boot】
我们之前在其中的一篇文章介绍过如何在spring boot中使用日志记录SLF4J. Spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持,如 ...
- 57. Spring 自定义properties升级篇【从零开始学Spring Boot】
之前在两篇文章中都有简单介绍或者提到过 自定义属性的用法: 25.Spring Boot使用自定义的properties[从零开始学Spring Boot] 51. spring boot属性文件之多 ...
- (45). Spring Boot MyBatis连接Mysql数据库【从零开始学Spring Boot】
大家在开发的时候,会喜欢jdbcTemplate操作数据库,有喜欢JPA操作数据库的,有喜欢MyBatis操作数据库的,对于这些我个人觉得哪个使用顺手就使用哪个就好了,并没有一定要使用哪个,个人在实际 ...
- Spring boot Mybatis 整合(完整版)
个人开源项目 springboot+mybatis+thymeleaf+docker构建的个人站点开源项目(集成了个人主页.个人作品.个人博客) 朋友自制的springboot接口文档组件swagge ...
随机推荐
- Cocos2d-x开源、跨平台的游戏引擎
from://http://blog.linguofeng.com/pages/language/c/Cocos2dx.html Cocos2d-x 开源.跨平台的游戏引擎 一.下载 http://c ...
- 架构:The Onion Architecture : part 3(洋葱架构:第三篇)(转载)
In my previous installments, I described what has become my approach to defining the architecture fo ...
- Java并发编程的艺术(六)——线程间的通信
多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同. 1. volatile.synchronized关键字 PS:关于volatile的详细介绍请移步至:Java ...
- Java中CAS详解
在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2 ...
- pip 安装错误 'ascii' codec can't encode characters
安装 python-dev既可解决 apt-get install python-dev
- 《RESTful Web APIs中文版》
<RESTful Web APIs中文版> 基本信息 原书名:RESTful Web APIs 原出版社: O'Reilly Media 作者: Leonard Richardson ...
- 短址服务 api
1 is.gd 他这个api简单: http://is.gd/api.php?longurl= 后面加网址就可以返回短址 2 Google URL Shortener API api地址: http ...
- 使用idea 在springboot添加本地jar包的方法 部署的时候本地jar没有包含的解决方法
需要添加dependency 和resources 否则发布的时候可能会缺少jar <dependency> <groupId>com.sap</groupId> ...
- mybatis中sql标签、where标签、foreach标签用法
<sql id="query_user_where"> <!-- 如果 userQueryVo中传入查询条件,再进行sql拼接--> <!-- tes ...
- 中文分词库及NLP介绍,jieba,gensim的一些介绍
六款中文分词软件介绍: https://blog.csdn.net/u010883226/article/details/80731583 里面有jieba, pyltp什么的.另外下面这个博客有不少 ...