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 ...
随机推荐
- 【python】python编码方式,chardet编码识别库
环境: python3.6 需求: 针对于打开一个文件,可以读取到文本的编码方式,根据默认的文件编码方式来获取文件,就不会出现乱码. 针对这种需求,python中有这个方式可以很好的解决: 解决策略: ...
- itunes connect 沙盒帐号地区的问题导致无法进行充值
项目代理给台湾发行,版本由项目提交appstore,台湾合作伙伴会进行测试.这里遇到一个问题,就是沙盒帐号测试的时候死活提示充值失败,不走正常的充值流程. 后来我分析了原因,主要是由于帐号的App S ...
- Android tips(八)-->Android Studio打包apk,aar,jar包
文本我们将讲解android studio打包apk,aar,jar包的相关知识.apk包就是android系统的安装包,这里没什么好说的,aar包是android中独有的类库包,而jar包是java ...
- [Network] okhttp3与旧版本okhttp的区别分析
cp from : https://www.jianshu.com/p/4a8c94b239b4 1.包名改变 包名改了由之前的 com.squareup.http.改为 okhttp3. 我们需要将 ...
- npm速度过慢的解决方案
因为npm连接的数据源网站太慢,可以使用淘宝提供的npm数据源, npm config set registry https://registry.npm.taobao.org 使用NPM(Node. ...
- [转]用国内软件源为Ubuntu的apt-get提速方法
FROM : http://www.jb51.net/os/Ubuntu/45293.html 刚装好Ubuntu系统之后根据需要还要安装一系列的软件,最省心的办法就是通过apt-get来进行 默 ...
- window.name实现的跨域数据传输 JavaScript跨域总结与解决办法
原文地址: http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html#m4 什么是跨域 1.document.domain+ifr ...
- java 小程序查看器 启动:未初始化小程序 解决方法
欢迎大家转载.为保留作者成果,转载请注明出处,http://blog.csdn.net/netluoriver,有些文件在资源中也能够下载.假设你没有积分.能够联系我索要! 在执行java程序的时候突 ...
- ArcEngine C++ 10 程序的运行环境,ArcEngine RT的授权
以前我一直以为 必须安装 Arcgis Desktop才可以授权,发现我错了,原来是这个样子的. 一.安装License manager,并授权许可server.txt 当然这个license也可以安 ...
- C/C++log日志库比较
事实上,在C的世界里面没有特别好的日志函数库(就像Java里面的的log4j,或者C++的log4cxx).C程序员都喜欢用自己的轮子.printf就是个挺好的轮子,但没办法通过配置改变日志的格式或者 ...