1. 动态SQL

1.1 介绍

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

    官网描述:

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

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

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


      - if
    - choose (when, otherwise)
    - trim (where, set)
    - foreach
    -------------------------------

1.2 搭建环境

  1. 新建一个表:blog

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

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

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

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

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

    @Test
    public void addInitBlog(){
    SqlSession session = MybatisUtils.getSession();
    BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = new Blog();
    blog.setId(IDUtil.genId());
    blog.setTitle("Mybatis如此简单");
    blog.setAuthor("妙啊");
    blog.setCreateTime(new Date());
    blog.setViews(9999); mapper.addBlog(blog); blog.setId(IDUtil.genId());
    blog.setTitle("Java如此简单");
    mapper.addBlog(blog); blog.setId(IDUtil.genId());
    blog.setTitle("Spring如此简单");
    mapper.addBlog(blog); blog.setId(IDUtil.genId());
    blog.setTitle("微服务如此简单");
    mapper.addBlog(blog); session.close();
    }

2. IF和WHERE语句

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

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

  1. 编写接口类

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

    • 传入的参数是map,那么在if标签中直接写的是map中的key,不用加#{}
    <select id="queryBlogIf" resultType="blog" parameterType="map">
    select *
    from blog
    <where>
    <if test="title != null">
    and title = #{title}
    </if>
    <if test="author != null">
    and author = #{author}
    </if>
    </where>
    </select>

3. SET语句

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

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

    <update id="updateBlog" parameterType="map">
    update blog
    <set>
    <if test="title != null">
    title = #{title},
    </if>
    <if test="author != null">
    author = #{author}
    </if>
    </set>
    where id = #{id}
    </update>

4. CHOOSE语句

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

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

    <select id="selectBlogChoose" resultType="blog" parameterType="map">
    select *
    from blog
    <where>
    <choose>
    <when test="title != null">
    title = #{title}
    </when>
    <when test="author != null">
    and author = #{author}
    </when>
    <otherwise>
    adn views = #{views}
    </otherwise>
    </choose>
    </where>
    </select>

5. SQL片段

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

  • 提取SQL片段:

    <sql id="if-title-author">
    <if test="title != null">
    title = #{title}
    </if>
    <if test="author != null">
    and author = #{author}
    </if>
    </sql>
  • 引用SQL片段:

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

  • 在 sql 片段中不要包括 where

6. ForEach

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

  1. 编写接口

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

    <select id="queryBlogForeach" parameterType="map" resultType="blog">
      select * from blog
       <where>
           <!--
    collection:指定输入对象中的集合属性
    item:每次遍历生成的对象
    open:开始遍历时的拼接字符串
    close:结束时拼接的字符串
    separator:遍历对象之间需要拼接的字符串
    select * from blog where 1=1 and (id=1 or id=2 or id=3)
         -->
           <foreach collection="ids"  item="id" open="and (" close=")" separator="or">
              id = #{id}
           </foreach>
       </where>
    </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. js 创建简单的表单同步验证器

    SyncValidate declare const uni: any; export interface SyncValidateOpt { [key: string]: SyncValidateF ...

  2. windows(wsl)下的trino编译和升级注意事项

    最近在进行旧版本的prestosql和prestodb升级相关的操作,尝试自己编译了一下,这里记录一下过程和遇到问题的处理. 因为Trino不支持windows下的编译,如果使用windows最方便的 ...

  3. SpringCloud Stream

    1.介绍 官网:https://www.springcloud.cc/spring-cloud-dalston.html#_spring_cloud_stream 1.1定义 是一个构建消息驱动微服务 ...

  4. HTTP常用请求头大揭秘

    本文为<三万长文50+趣图带你领悟web编程的内功心法>第四个章节. 4.HTTP常用请求头大揭秘 上面列出了报文的各种请求头.响应头.状态码,是不是感到特别晕呢.这节我们就专门挑一些最常 ...

  5. Mysql通过binlog恢复误update的数据

    事件: 在生产库执行update时只添加了STATUS(状态)条件,将所有状态为'E'的数据全部改为了'D' 思路: 操作步骤主要参考自文章:https://blog.csdn.net/weixin_ ...

  6. Redis操作指南

    目录 Redis安装与使用教程 一.Redis介绍 1.redis安装 2.redis与mysql的异同 3.redis与memcache的异同 二.Redis操作 1.启动服务 2.密码管理 3.连 ...

  7. Java基础自学小项目

    实现一个基于文本界面的<家庭记账软件> 需求:能够记录家庭的收入,支出,并能够收支明细表 主要涉及一下知识点: - 局部变量和基本数据类型 - 循环语句 - 分支语句 - 方法调用和返回值 ...

  8. Java文件字节流

    //输出和输入流 package com.kangkang.IO; import com.sun.xml.internal.ws.util.xml.CDATA; import java.io.File ...

  9. 关于使用C3P0程序报错Having failed to acquire a resource, com.mchange.v2.resourcepool的问题

    由于是新手的问题,C3P0的使用时严格跟着视频来的,但是问题却来的很突然 在导入了三个包以及创建了路径以后 进行测试 class JdbcutilsTest { @Test void TestGetC ...

  10. Django 报错 Reverse for 'content' not found. 'content' is not a valid view function or pattern name.

    Django 报错 Reverse for 'content' not found. 'content' is not a valid view function or pattern name. 我 ...