脚本sql

XML配置方式的动态SQL我就不讲了,有兴趣可以自己了解,下面是用<script>的方式把它照搬过来,用注解来实现。适用于xml配置转换到注解配置
@Select("<script>select * from user <if test=\"id !=null \">where id = #{id} </if></script>")
public List<User> findUserById(User user);

很明显,在java中写xml可读性和维护性太差,尤其当SQL很长时,这样写是很痛苦的。

在方法中构建sql

dao接口中是不能写实现的,所以这里借用内部类来生成动态SQL。增改删也有对应的@InsertProvider、@UpdateProvider、@DeleteProvider
 
@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;
}
}

这比<script>更加清晰,适用于查询语句不是很长、条件不多的场景,SQL很直观。但是在写很长的SQL时,这样拼接SQL同样会很痛苦

结构化SQL

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();
}
这是把前面的内部类改造一下
SELECT:表示要查询的字段,如果一行写不完,可以在第二行再写一个SELECT,这两个SELECT会智能的进行合并而不会重复
FROM和WHERE:跟SELECT一样,可以写多个参数,也可以在多行重复使用,最终会智能合并而不会报错
这样语句适用于写很长的SQL时,能够保证SQL结构清楚。便于维护,可读性高。但是这种自动生成的SQL和HIBERNATE一样,在实现一些复杂语句的SQL时会束手无策。所以需要根据现实场景,来考虑使用哪一种动态SQL
上面的例子只是最基本的用法:更多详细用法,可以参考mybatis中文网的专门介绍
http://www.mybatis.org/mybatis-3/zh/statement-builders.html

List传值错误

动态SQL中,有时要对批量数据进行处理,难免会使用list做为参数
 
@SelectProvider(type = UserDaoProvider.class, method = "find")
public List<Map> find(List list); class UserDaoProvider {
public String find(List list) {

这是一个最简单的list传参,但是在运行时会报传参错误。这是mybatis内部机制造成的,其参数需要是key/value结构,当遇到这里不是key/value结构的list时,mybatis会自己把它转换成key/value结构,key就是他的名字"list",value就是他的值List,要正确传参需要使用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");

最新文章

  1. 索引深入浅出(5/10):非聚集索引的B树结构在堆表
  2. 透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化
  3. Rime 鼠须管 配色方案
  4. mysql多表查询例子
  5. 泛——复习js高级第三版
  6. jQuery代码性能小细节
  7. A的href和onclick
  8. MINA源码分析
  9. iOS小知识点大杂烩
  10. python--lambda和def函数
  11. 【RevolC FaeLoN Uva 10972】
  12. Caffe框架,了解三个文件
  13. AlertConfirmDialog【基于AlertDialog的确认取消对话框】
  14. nginx/php的redis模块扩展
  15. matlab2014a 转化c语言
  16. hdu3949 异或空间 + 求矩阵的主元
  17. Linux下安装配置virtualenv与virtualenvwrapper
  18. Vue(十七)模块化开发
  19. TIdHTTP get参数带中文解决方法--请求报文
  20. swoole深入学习 1. swoole初始

热门文章

  1. 设计原则:多使用Specialized Types
  2. Android 判断是否能真正上网
  3. Pandas删除数据的几种情况
  4. .NET零基础入门之02:源码控制管理器的使用
  5. ThreadLocal 与 Request 和 Session 之关联
  6. C# ApartmentState 枚举,指定线程单元状态
  7. 在Windows7/8/10上,安装IIS
  8. 使用Idea创建多Module工程
  9. 一种开源的分布式消息系统Nats
  10. Centos 7安装protobuf3.6.1