本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接

https://space.bilibili.com/95256449?spm_id_from=333.788.b_765f7570696e666f.2

动态SQL(Dynamic SQL)

  • 动态 SQL 是 MyBatis 的强大特性之一。

  • 其实就是简化了拼接SQL的方式。比如实际业务中,输入了用户名时,要按用户名查询是非常常见的,动态SQL其实就是Mybatis里的方式。

if(username!=null&&!"".equals(username)){
sb.append("and username = '"+username+"' " );
}
  • 在Mapper.xml文件中使用以下四种符号实现(和JSTL很像)。

    • if

    • choose (when, otherwise)

    • trim (where, set)

    • foreach

环境准备

拓展

  • 实体类

public class Blog {

private int id;
private String title;
private String author;
private Date createTime;
private int views;
}
注意:实体类的Date是createTime,而数据库中的是create_time,字段不一样,但是可以通过主配置文件的setting,自动把驼峰规则修改为下划线---->createTime的T自动变为_t。
    <settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
  • UUID--雪花算法自动生成pk

public class IDutils {
public static String getId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
  • Mapper.xml

    <insert id="addBlog" parameterType="blog">
<!--注意value中传入的时间是实体类的名称,insert进数据库写的是字段名-->
insert into mybatis.blog (id,title,author,create_time,views)
values (#{id},#{title},#{author},#{createTime},#{views})
</insert>
  • 测试类

    • 日期的new Date()虽然在控制台输出是,但是只要实体类和数据库的格式都是date,那么就会自动转换成数据库的格式而不需要手动转换。


@Test
public void addInitBlog(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDutils.getId());
blog.setTitle("Mybatis学习");
blog.setAuthor("张三");
blog.setCreateTime(new Date());
blog.setViews(222);
System.out.println(blog.toString());
mapper.addBlog(blog);
blog.setId(IDutils.getId());
blog.setTitle("Java学习");
mapper.addBlog(blog);
blog.setId(IDutils.getId());
blog.setTitle("Spring学习");
mapper.addBlog(blog);
blog.setId(IDutils.getId());
blog.setTitle("SpringMVC学习");
mapper.addBlog(blog);
sqlSession.commit();
sqlSession.close();
}

if

  • Mapper接口

    //查询博客
List<Blog> queryBlogIF(Map map);
  • Mapper.xml

    • 增加if条件即可

    <select id="queryBlogIF" parameterType="map" resultType="blog">
select * from blog t where 1=1
<if test="title!=null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</select>
  • 测试类,通过map传参

    @Test
public void queryBlogIf(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
// map.put("title","Mybatis学习");
map.put("author","李四");

List<Blog> blogs = mapper.queryBlogIF(map);
for (Blog blog : blogs) {
System.out.println(blog);
}

sqlSession.close();
}

choose和where

  • 和if的区别是,choose中只会选择一个执行,就和switch一样

  • Mapper.xml

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

where:

  • 上面的例子中增加了where标签

  • 如果不使用where 1=1,可以使用官方给的标签<where>,然后第一个语句不写连接符就可以了

  • (其实第一句也加and测试下来也没问题,而且官方描述是子句开头是and或者or的,作为第一句语句时会自动去除and和or,写了更整齐,以后用多了再看吧)。

  • 测试类

        @Test
    public void queryBlogIf(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    // map.put("title","Mybatis学习");
    map.put("author","李四");

    List<Blog> blogs = mapper.queryBlogChoose(map);
    for (Blog blog : blogs) {
    System.out.println(blog);
    }
    sqlSession.close();
    }

set

  • set只限于update中,和where的用法类似

  • Mapper.xml

    <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>
 
  • 测试类

    @Test
public void updateblog(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","Mybatis学习1212");
map.put("id","1");
mapper.updateBlog(map);
sqlSession.commit();
sqlSession.close();
}

foreach

  • 对于in语句,可以使用foreach对集合进行遍历

  • 比如对于以下语句,如果2、4、6用map来传,xml文件里就要定义3个变量了,这时候可以用foreach

select * from blog where id in ('2','4','6')
  • foreach

<!--collection--传入集合的名称
item--从集合遍历时每个元素的引用名称
open--循环前拼接的内容
separator--每个元素之间间隔的内容
close--循环后拼接的内容
index--循环时下标的序号名称,很少会使用到
-->
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
id in
<foreach collection="ids" item="idv" open="(" separator="," close=")">
#{idv}
</foreach>
</where>
</select>
  • 测试类

    @Test
public void queryBlogForeach(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
ArrayList<Integer> ids = new ArrayList<>();
ids.add(2);
ids.add(4);
ids.add(6);
HashMap map = new HashMap();
map.put("ids",ids);

List<Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}

trim

  • 这个标签其实一般不会用到,因为where、set标签一般就够用了。

  • 假如没有where 标签,使用trim也可以达到相同的效果:

  • trim有3个属性

    • prefix:标签内的语句会用这个属性开头

    • suffix:标签内的语句会用这个结尾

    • prefixOverrides:标签内的第一个语句是这个属性开头,会去掉

    • suffixOverrides:标签内最后一个语句是这个结尾,会去掉

<trim prefix="WHERE" prefixOverrides="AND |OR " suffixOverrides=",">
...
</trim>
  • 示例:其实就和where完全一样

    <select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<trim prefix="where" prefixOverrides="and|or" >
and id in
<foreach collection="ids" item="idv" open="(" separator="," close=")">
#{idv}
</foreach>
</trim>
</select>

SQL片段

  • 把公共的SQL抽取出来,方便复用。

  • Mapper.xml

<!--把公共部分抽取出来-->
<sql id="ifta">
<if test="title!=null">
and title = #{title}
</if>
<if test="author!=null">
and author = #{author}
</if>
</sql>
<!--通过ID可以进行调用-->
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from blog t
<where>
<include refid="ifta"/>
</where>
</select>

注意事项:

  • 最好基于单表来定义SQL片段

  • 不要存在where标签

MyBatis(九):动态SQL的更多相关文章

  1. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...

  2. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

  3. mybatis 使用动态SQL

    RoleMapper.java public interface RoleMapper { public void add(Role role); public void update(Role ro ...

  4. MyBatis框架——动态SQL、缓存机制、逆向工程

    MyBatis框架--动态SQL.缓存机制.逆向工程 一.Dynamic SQL 为什么需要动态SQL?有时候需要根据实际传入的参数来动态的拼接SQL语句.最常用的就是:where和if标签 1.参考 ...

  5. 使用Mybatis实现动态SQL(一)

    使用Mybatis实现动态SQL 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 写在前面:        *本章节适合有Mybatis基础者观看* 前置讲解 我现在写一个查询全部的 ...

  6. MyBatis探究-----动态SQL详解

    1.if标签 接口中方法:public List<Employee> getEmpsByEmpProperties(Employee employee); XML中:where 1=1必不 ...

  7. mybatis中的.xml文件总结——mybatis的动态sql

    resultMap resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功. 如果sql查询字段名和pojo的属性名不一致,可以通过re ...

  8. mybatis.5.动态SQL

    1.动态SQL,解决关联sql字符串的问题,mybatis的动态sql基于OGNL表达式 if语句,在DeptMapper.xml增加如下语句; <select id="selectB ...

  9. MyBatis的动态SQL详解-各种标签使用

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) ...

  10. 利用MyBatis的动态SQL特性抽象统一SQL查询接口

    1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...

随机推荐

  1. 这些MongoDB的隐藏操作你真的都掌握了吗?反正我是刚知道

    背景 最近公司系统还原用户时偶尔会出现部分用户信息未还原成功的问题,最为开发人员,最头疼的不是代码存在bug,而是测试发现了bug,但一旦我去重现,它就不见了.Are you kidding me? ...

  2. ggplot2(2) 从qplot开始入门

    2.1 简介 qplot的意思是快速作图(quick plot). qplot是一种快捷方式,如果您已习惯于使用基础plot(),则可以使用它.它可以使用一致的调用模式快速创建许多不同类型的图. qp ...

  3. [头脑风暴] 解读Docker Bridge网络模型

    背景 这几天在研究Kubernetes, 遇到一个有意思的nodejs镜像:luksa/kubia # 不带端口映射启动容器docker run -it -d luksa/kubia# 连接到默认的B ...

  4. Spark实战--寻找5亿次访问中,访问次数最多的人

    问题描述 对于一个大型网站,用户访问量尝尝高达数十亿.对于数十亿是一个什么样的概念,我们这里可以简单的计算一下.对于一个用户,单次访问,我们通常会记录下哪些数据呢? 1.用户的id 2.用户访问的时间 ...

  5. CSS每日学习笔记(1)

    7.30.2019 1.CSS 文本属性 属性 描述 color 设置文本颜色 direction 设置文本方向. line-height 设置行高. letter-spacing 设置字符间距. t ...

  6. AspNetCore3.1_Secutiry源码解析_5_Authentication_OAuth

    title: "AspNetCore3.1_Secutiry源码解析_5_Authentication_OAuth" date: 2020-03-24T23:27:45+08:00 ...

  7. 分享CCNTFS小工具,在 macOS 中完全读写、修改、访问Windows NTFS硬盘的文件,无须额外的驱动(原生驱动)更稳定,简单设置即可高速传输外接NTFS硬盘文件

    CCNTFS [ 下载 ] 在 macOS 中完全读写.修改.访问Windows NTFS硬盘的文件,无须额外的驱动(原生驱动)更稳定,安装后进行简单设置即可高速传输外接NTFS硬盘文件,可全程离线使 ...

  8. Chrome EC框架探索_0.0_引言

    0.0 引言 嵌入式硬件抽象框架常常面临着这样的尴尬:封装层次较高的(arduino,mbed)不能充分暴露必要的API并面临着性能问题,封装层次较低的(HAL,LL)接口复杂且开发困难.近日发现的一 ...

  9. 201771010103 陈亚茹 《面向对象程序设计(java)》第一周学习总结

    本人学号<面向对象程序设计(java)>第一周学习总结 第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com https://w ...

  10. Verbal Arithmetic Puzzle

    2020-01-02 12:09:09 问题描述: 问题求解: 这个问题不就是小学奥数题么?都知道要暴力枚举,但是如何巧妙的枚举才是问题的关键.在打比赛的时候,我用了全排列算法,TLE了. 借鉴了别人 ...