1. 动态SQL

1.1 介绍

  • 概念:**动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.*

    官网描述:

    MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

    虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。

    动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。


    1. - if
    2. - choose (when, otherwise)
    3. - trim (where, set)
    4. - foreach
    5. -------------------------------

1.2 搭建环境

  1. 新建一个表:blog

    1. CREATE TABLE `blog` (
    2. `id` varchar(50) NOT NULL COMMENT '博客id',
    3. `title` varchar(100) NOT NULL COMMENT '博客标题',
    4. `author` varchar(30) NOT NULL COMMENT '博客作者',
    5. `create_time` datetime NOT NULL COMMENT '创建时间',
    6. `views` int(30) NOT NULL COMMENT '浏览量'
    7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  2. 插件IDUtil工具类

    1. public class IDUtil {
    2.    public static String genId(){
    3.        return UUID.randomUUID().toString().replaceAll("-","");
    4.   }
    5. }
  3. 编写实体类

    1. public class Blog {
    2.    private String id;
    3.    private String title;
    4.    private String author;
    5.    private Date createTime;
    6.    private int views;
    7. // 无参构造
    8. // 有参构造
    9. // get、set、toString
    10. }
  4. 编写Mapper接口及mapper配置文件

    1. public interface BlogMapper {
    2. int addBlog(Blog blog);
    3. }
    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="top.linzeliang.mapper.BlogMapper">
    6. <insert id="addBlog" parameterType="blog">
    7. insert into blog (id, title, author, create_time, views)
    8. values (#{id},#{title},#{author},#{createTime},#{views});
    9. </insert>
    10. </mapper>
  5. 在MyBatis配置文件中设置下驼峰线自动转换

    1. <settings>
    2. <setting name="mapUnderscoreToCamelCase" value="true"/>
    3. <setting name="logImpl" value="STDOUT_LOGGING"/>
    4. </settings>
    5. <!--注册Mapper.xml-->
    6. <mappers>
    7. <mapper resource="top/linzeliang/mapper/BlogMapper.xml"/>
    8. </mappers>
  6. 初始化博客方法

    1. @Test
    2. public void addInitBlog(){
    3. SqlSession session = MybatisUtils.getSession();
    4. BlogMapper mapper = session.getMapper(BlogMapper.class);
    5. Blog blog = new Blog();
    6. blog.setId(IDUtil.genId());
    7. blog.setTitle("Mybatis如此简单");
    8. blog.setAuthor("妙啊");
    9. blog.setCreateTime(new Date());
    10. blog.setViews(9999);
    11. mapper.addBlog(blog);
    12. blog.setId(IDUtil.genId());
    13. blog.setTitle("Java如此简单");
    14. mapper.addBlog(blog);
    15. blog.setId(IDUtil.genId());
    16. blog.setTitle("Spring如此简单");
    17. mapper.addBlog(blog);
    18. blog.setId(IDUtil.genId());
    19. blog.setTitle("微服务如此简单");
    20. mapper.addBlog(blog);
    21. session.close();
    22. }

2. IF和WHERE语句

  • if语句就是判断是否满足某个条件,满足的话就添加标签内容到sql语句中
  • where语句:如果包含的标签中含有返回值得话,他就会自动插入一个where,如果返回值的内容的第一个开头是 and 或者 or,则会自动剔除

需求:根据作者名字和博客名字来查询博,如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询

  1. 编写接口类

    1. List<Blog> queryBlogIf(Map map);
  2. 编写对应的mapper配置文件

    • 传入的参数是map,那么在if标签中直接写的是map中的key,不用加#{}
    1. <select id="queryBlogIf" resultType="blog" parameterType="map">
    2. select *
    3. from blog
    4. <where>
    5. <if test="title != null">
    6. and title = #{title}
    7. </if>
    8. <if test="author != null">
    9. and author = #{author}
    10. </if>
    11. </where>
    12. </select>

3. SET语句

  • 如果在进行更新操作的时候,含有 set 关键词,则使用set标签,效果和where也是一样的
  1. 编写接口方法

    1. int updateBlog(Map map);
  2. 编写对应的mapper配置文件

    1. <update id="updateBlog" parameterType="map">
    2. update blog
    3. <set>
    4. <if test="title != null">
    5. title = #{title},
    6. </if>
    7. <if test="author != null">
    8. author = #{author}
    9. </if>
    10. </set>
    11. where id = #{id}
    12. </update>

4. CHOOSE语句

  • 有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句
  1. 编写接口方法

    1. List<Blog> queryBlogChoose(Map map);
  2. 编写对应的mapper配置文件

    1. <select id="selectBlogChoose" resultType="blog" parameterType="map">
    2. select *
    3. from blog
    4. <where>
    5. <choose>
    6. <when test="title != null">
    7. title = #{title}
    8. </when>
    9. <when test="author != null">
    10. and author = #{author}
    11. </when>
    12. <otherwise>
    13. adn views = #{views}
    14. </otherwise>
    15. </choose>
    16. </where>
    17. </select>

5. SQL片段

  • 有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用

  • 提取SQL片段:

    1. <sql id="if-title-author">
    2. <if test="title != null">
    3. title = #{title}
    4. </if>
    5. <if test="author != null">
    6. and author = #{author}
    7. </if>
    8. </sql>
  • 引用SQL片段:

    1. <select id="queryBlogIf" parameterType="map" resultType="blog">
    2. select * from blog
    3. <where>
    4. <!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
    5. <include refid="if-title-author"></include>
    6. <!-- 在这里还可以引用其他的 sql 片段 -->
    7. </where>
    8. </select>
  • 最好基于 单表来定义 sql 片段,提高片段的可重用性

  • 在 sql 片段中不要包括 where

6. ForEach

需求:我们需要查询 blog 表中 id 分别为1,2,3的博客信息

  1. 编写接口

    1. List<Blog> queryBlogForeach(Map map);
  2. 编写对应的mapper配置文件

    1. <select id="queryBlogForeach" parameterType="map" resultType="blog">
    2.   select * from blog
    3.    <where>
    4.        <!--
    5. collection:指定输入对象中的集合属性
    6. item:每次遍历生成的对象
    7. open:开始遍历时的拼接字符串
    8. close:结束时拼接的字符串
    9. separator:遍历对象之间需要拼接的字符串
    10. select * from blog where 1=1 and (id=1 or id=2 or id=3)
    11.      -->
    12.        <foreach collection="ids"  item="id" open="and (" close=")" separator="or">
    13.           id = #{id}
    14.        </foreach>
    15.    </where>
    16. </select>
  3. 总结:其实动态sql语句的编写往往就是一个拼接的问题,为了保证拼接准确,我们最好首先要写原生的sql语句出来,然后在通过mybatis动态sql对照着改,防止出错

MyBatis笔记(六)的更多相关文章

  1. Mybatis笔记六:Mybatis中SqlSessionFactoryBuilder/SqlSessionFactory/SqlSession/映射器实例的作用域(Scope)和生命周期

    SqlSessionFactoryBuilder 这个类可以被实例化.使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了.因此 SqlSessionFactoryBuilder ...

  2. Spring Boot 学习笔记(六) 整合 RESTful 参数传递

    Spring Boot 学习笔记 源码地址 Spring Boot 学习笔记(一) hello world Spring Boot 学习笔记(二) 整合 log4j2 Spring Boot 学习笔记 ...

  3. 《MFC游戏开发》笔记六 图像双缓冲技术:实现一个流畅的动画

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9334121 作者:七十一雾央 新浪微博:http:/ ...

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  6. Python学习笔记六

    Python课堂笔记六 常用模块已经可以在单位实际项目中使用,可以实现运维自动化.无需手工备份文件,数据库,拷贝,压缩. 常用模块 time模块 time.time time.localtime ti ...

  7. Mybatis笔记二:接口式编程

    目录 旧方法的弊端 接口式编程 接口式编程的好处 接口式编程的增删改查 旧方法的弊端 在Mybatis笔记一中,我们使用命名空间+id的方式实现了Mybatis的执行,不过这里的命名空间是我们随便写的 ...

  8. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. Django开发笔记六

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.登录功能完善 登录成功应该是重定向到首页,而不是转发 ...

  10. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

随机推荐

  1. nvm install node error

    nvm install node error ➜ mini-program-all git:(master) nvm install 10.15.3 Downloading and installin ...

  2. React-Native Tutorials

    React-Native Tutorials https://egghead.io/courses/react-native-fundamentals part free https://egghea ...

  3. Egg.js 是什么?

    Egg.js 是什么? 阿里巴巴出 Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本. 注:Egg.js 缩写为 Egg 设 ...

  4. [转]C++语言的历史和标准化

    转:https://blog.csdn.net/lemonrabbit1987/article/details/48222339 1979年4月,贝尔实验室的Bjarne Stroustrup(本贾尼 ...

  5. 1004 Counting Leaves ——PAT甲级真题

    1004 Counting Leaves A family hierarchy is usually presented by a pedigree tree. Your job is to coun ...

  6. 死磕Spring之IoC篇 - BeanDefinition 的加载阶段(XML 文件)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  7. 解决java POI导入Excel超时问题

    由于要导入大量数据,后台会耗费很长时间,导致超时. 本项目前端request.js中设定的超时时间为150s. const service = axios.create({ baseURL: base ...

  8. Java并发之ThreadPoolExecutor源码解析(二)

    ThreadPoolExecutor ThreadPoolExecutor是ExecutorService的一种实现,可以用若干已经池化的线程执行被提交的任务.使用线程池可以帮助我们限定和整合程序资源 ...

  9. 剑指 Offer 44. 数字序列中某一位的数字 + 找规律 + 数位

    剑指 Offer 44. 数字序列中某一位的数字 Offer_44 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author Wale ...

  10. AOP(面向切面编程)大概了解一下

    前言 上一篇在聊MemoryCache的时候,用到了Autofac提供的拦截器进行面向切面编程,很明显能体会到其优势,既然涉及到了,那就趁热打铁,一起来探探面向切面编程. 正文 1. 概述 在软件业, ...