实现动态SQL的四种方式:

1、XML配置

使用XML配置动态SQL,细节不表,详参:《MyBatis快速上手与知识点总结》 - 5.4 多条件查询 - 动态查询

2、脚本SQL

  • 使用注解实现,将XML文件的内容转换为注释即可
  • 当然,这种方式可读性差,且难以维护
@Select("<script>select * from user <if test=\"id !=null \">where id = #{id} </if></script>")
public List<User> findUserById(User user);

3、在方法中构建SQL

  • Dao层接口不写实现,次数使用内部类来生成动态SQL,并传入 @SelectProvider 注释
  • 增改删也有对应的 @InsertProvider、@UpdateProvider、@DeleteProvider 注释
  • 相比于脚本SQL更加清晰,比较直观,但是如果SQL过长的话,拼接会非常麻烦
@Mapper
public interface MybatisDao {
//使用UserDaoProvider类的findUserById方法来生成sql
@SelectProvider(type = UserDaoProvider.class, method = "findUserById")
public List<User> findUserById(User user); class UserDaoProvider {
public String findUserById(User user) {
String sql = "SELECT * FROM user";
if(user.getId()!=null){
sql += " where id = #{id}";
}
return sql;
}
}
}

4、结构化SQL

  • 这是把前面的内部类改造一下:

    • SELECT:表示要查询的字段,如果一行写不完,可以在第二行再写一个SELECT,这两个SELECT会智能的进行合并而不会重复
    • FROM 和 WHERE:跟SELECT一样,可以写多个参数,也可以在多行重复使用,最终会智能合并而不会报错。
  • 这样语句适用于写很长的SQL时,能够保证SQL结构清楚。便于维护,可读性高。
  • 但是这种自动生成的SQL和HIBERNATE一样,在实现一些复杂语句的SQL时会束手无策。所以需要根据现实场景,来考虑使用哪一种动态SQL
  • 上面的例子只是最基本的用法:更多详细用法,可以参考mybatis中文网的专门介绍:

    http://www.mybatis.org/mybatis-3/zh/statement-builders.html
@Mapper
public interface MybatisDao {
//使用UserDaoProvider类的findUserById方法来生成sql
@SelectProvider(type = UserDaoProvider.class, method = "findUserById")
public List<User> findUserById(User user); public String findUserById(User user) {
return new SQL(){{
SELECT("id,name");
SELECT("other");
FROM("user");
if(user.getId()!=null){
WHERE("id = #{id}");
}
if(user.getName()!=null){
WHERE("name = #{name}");
}
//从这个toString可以看出,其内部使用高效的StringBuilder实现SQL拼接
}}.toString();
}
}

关于动态SQL的List传值错误问题

动态SQL中,有时要对批量数据进行处理,难免会使用list做为参数

1、错误代码

  • 这是一个最简单的list传参,但是在运行时会报传参错误。
  • 这是mybatis内部机制造成的,其参数需要是key/value结构,当遇到这里不是 key/value结构的list时,mybatis会自己把它转换成key/value结构,key就是他的名字"list",value就是他的值 list 对象
@SelectProvider(type = UserDaoProvider.class, method = "find")
public List<Map> find(List list); class UserDaoProvider {
public String find(List list) {
}
}

2、解决错误

要正确传参需要使用key/value结构的map,如下:

@SelectProvider(type = UserDaoProvider.class, method = "find")
public List<Map> find(List list); class UserDaoProvider {
public String find(Map map) {
List list = (List) map.get("list");
}
}

SpringBoot+MyBatis的动态SQL、使用动态SQL时List传值错误解决方案的更多相关文章

  1. 数据库通过sql备份脚本恢复时,报错误The user specified as a definer ('root'@'%') does not exist

    数据库通过sql备份脚本恢复时,报错误The user specified as a definer ('root'@'%') does not exist 当出现这个错误,意思是某个数据库对象的定义 ...

  2. SpringBoot + MyBatis(注解版),常用的SQL方法

    一.新建项目及配置 1.1 新建一个SpringBoot项目,并在pom.xml下加入以下代码 <dependency> <groupId>org.mybatis.spring ...

  3. OC 动态类型,动态绑定,动态加载

    OC 动态类型,动态绑定,动态加载 Objective-C具有相当多的动态特性,基本的,也是经常被提到和用到的有 动态类型(Dynamic typing) 动态绑定(Dynamic binding) ...

  4. SpringBoot使用Mybatis注解开发教程-分页-动态sql

    代码示例可以参考个人GitHub项目kingboy-springboot-data 一.环境配置 1.引入mybatis依赖 compile( //SpringMVC 'org.springframe ...

  5. Spring Boot入门系列(十九)整合mybatis,使用注解实现动态Sql、参数传递等常用操作!

    前面介绍了Spring Boot 整合mybatis 使用注解的方式实现数据库操作,介绍了如何自动生成注解版的mapper 和pojo类. 接下来介绍使用mybatis 常用注解以及如何传参数等数据库 ...

  6. MyBatis学习 之 三、动态SQL语句

    目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...

  7. Mybatis第三篇【动态SQL】

    动态SQL 何为动态SQL??回顾一下我们之前写的SSH项目中,有多条件查询的情况,如下图 我们当时刚开始做的时候,是需要在Controller中判断SQL是否已经有条件了,因为SQL语句需要拼接起来 ...

  8. MyBatis之基于XML的动态SQL

    先说下我的梦想,大学的时候一直想着是能开店卖胡辣汤,到目前依然还是我的梦想,上周一家出版社联系我问我有没有时间可以合作出书,这也是我的梦想之一,想了想还是放弃了,至少觉得目前不行,毕竟工作还不到五年, ...

  9. Mybatis:缓存,动态SQL,注解SQL以及动态标签使用

    1 转义字符 字符 转义 描述 < < 小于 <= <= 小于等于 > > 大于 >= >= 大于等于 <> <> 不等于 &a ...

  10. Mybatis中输入输出映射和动态Sql

    一.输入映射 我们通过配置parameterType的值来指定输入参数的类型,这些类型可以是简单数据类型.POJO.HashMap等数据类型 1.简单类型 2.POJO包装类型 ①这是单表查询的时候传 ...

随机推荐

  1. ES6 学习笔记(十三)promise的简单使用

    1.什么是promise 在JavaScript中,我们经常会用到回调函数,而回调函数的使用让我们没法使用return,throw等关键字.JS引用promise正好解决了这个问题. promise单 ...

  2. linux系统启动达梦迁移工具失败解决办法

    在达梦数据库服务端的tool目录下执行./dts来启动迁移工具,迁移工具启动前出现报错,以下提供几种遇到问题的解决办法: 1. 报错1: 执行./dts,报错提示: [yyuser@qy-ggyf-z ...

  3. TypeScript(基础篇)day01

    一.TS介绍 1.1 简介 ts是2012年由微软开发,在js的基础上添加了类型支持 1.2 优劣势 优势 :任何位置都有代码提示,增加效率:类型系统重构更容易:使用最新的ECMAscript语法 劣 ...

  4. ubuntu生成pem证书连接服务器(已验证)

    SSH 密钥认证是什么? 与用户密码登录相比,SSH 密钥认证更安全,因为只有拥有密钥的人才能连接,并且密钥通过不同的算法进行了很好的加密.它还通过无密码登录使 SSH 连接变得简单. 这个搞两个方案 ...

  5. 3.JS

    1.简介 JavaScript 因为互联网而生,紧随着浏览器的出现而问世 1997年7月,ECMAScript 1.0发布. 1998年6月,ECMAScript 2.0版发布. 1999年12月,E ...

  6. perl reverse函数

    转载至  Perl - 列表 - reverse 操作 reverse(逆转)操作将输入的一串列表(可能是数组)按相反的顺序返回. my @arr=("Head_PMA1",&qu ...

  7. Go语言核心36讲31

    我们在前两篇文章中讨论了互斥锁.读写锁以及基于它们的条件变量,先来总结一下. 互斥锁是一个很有用的同步工具,它可以保证每一时刻进入临界区的goroutine只有一个.读写锁对共享资源的写操作和读操作则 ...

  8. ifconfig命令的使用

    ifconfig命令 用途:配置或显示TCP/IP网络的网络接口参数. *1.通过--help学习ifconfig的使用 点击查看代码 [root@rocky8 ~]# ifconfig --help ...

  9. i春秋Fuzzing

    先查看源码...没东西,抓包 发现也没什么,但是右边有个提示hint: ip,Large internal network(最大内网ip) 可能需要我们伪造代码进行访问,这还不简单,直接在reques ...

  10. Scrum 框架的四个会议还适用于哪些敏捷方法?

    敏捷转型需要深入理解概念和思维,团队才能更好的进行实践.本文将通过介绍Scrum框架的四个会议还适用于哪些敏捷方法,来让大家更直观的理解敏捷转型. 本文整理自:PingCode 敏捷大学,转载请注明链 ...