MyBatis学习总结-06-动态SQL

简介
什么是动态SQL:动态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-------------------------------

搭建环境

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

1、创建Mybatis基础工程
2、IDutil工具类

public class IDUtil {public static String genId(){return UUID.randomUUID().toString().replaceAll("-","");}}

3、实体类编写 【注意set方法作用】

import java.util.Date;public class Blog {private String id;private String title;private String author;private Date createTime;private int views;//set,get....
}

4、编写Mapper接口及xml文件

public interface BlogMapper {}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.BlogMapper"></mapper>

5、mybatis核心配置文件,下划线驼峰自动转换

<settings><setting name="mapUnderscoreToCamelCase" value="true"/><setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--注册Mapper.xml-->
<mappers><mapper resource="mapper/BlogMapper.xml"/>
</mappers>

6、插入初始数据

编写接口

//新增一个博客
int addBlog(Blog blog);

sql配置文件

<insert id="addBlog" parameterType="blog">insert into blog (id, title, author, create_time, views)values (#{id},#{title},#{author},#{createTime},#{views});
</insert>

初始化博客方法

@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();
}

if 语句

需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
1、编写接口类

//需求1
List<Blog> queryBlogIf(Map map);

2、编写SQL语句

<!--需求1:
根据作者名字和博客名字来查询博客!
如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
select * from blog where title = #{title} and author = #{author}
-->
<select id="queryBlogIf" parameterType="map" resultType="blog">select * from blog where<if test="title != null">title = #{title}</if><if test="author != null">and author = #{author}</if>
</select>

3、测试

@Test
public void testQueryBlogIf(){SqlSession session = MybatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("title","Mybatis如此简单");map.put("author","陈陈陈");List<Blog> blogs = mapper.queryBlogIf(map);System.out.println(blogs);session.close();
}

这样写我们可以看到,如果 author 等于 null,那么查询语句为 select * from user where title=#{title},但是如果title为空呢?那么查询语句为 select * from user where and author=#{author},这是错误的 SQL 语句,如何解决呢?请看下面的 where 语句!

Where

修改上面的SQL语句;

<select id="queryBlogIf" parameterType="map" resultType="blog">select * from blog<where><if test="title != null">title = #{title}</if><if test="author != null">and author = #{author}</if></where>
</select>

这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。

Set
同理,上面的对于查询 SQL 语句包含 where 关键字,如果在进行更新操作的时候,含有 set 关键词,我们怎么处理呢?

1、编写接口方法

int updateBlog(Map map);

2、sql配置文件

<!--注意set是用的逗号隔开-->
<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>

3、测试

@Test
public void testUpdateBlog(){SqlSession session = MybatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("title","动态SQL");map.put("author","秦疆");map.put("id","9d6a763f5e1347cebda43e2a32687a77");mapper.updateBlog(map);session.close();
}

choose语句

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

1、编写接口方法

List<Blog> queryBlogChoose(Map map);

2、sql配置文件

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

3、测试类

@Test
public void testQueryBlogChoose(){SqlSession session = MybatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, Object> map = new HashMap<String, Object>();map.put("title","Java如此简单");map.put("author","陈陈陈");map.put("views",9999);List<Blog> blogs = mapper.queryBlogChoose(map);System.out.println(blogs);session.close();
}

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

Foreach

将数据库中前三个数据的id修改为1,2,3;

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

1、编写接口

List<Blog> queryBlogForeach(Map map);

2、编写SQL语句

<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、测试

@Test
public void testQueryBlogForeach(){SqlSession session = MybatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap map = new HashMap();List<Integer> ids = new ArrayList<Integer>();ids.add(1);ids.add(2);ids.add(3);map.put("ids",ids);List<Blog> blogs = mapper.queryBlogForeach(map);System.out.println(blogs);session.close();
}

提取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

Foreach

将数据库中前三个数据的id修改为1,2,3;

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

1、编写接口

List<Blog> queryBlogForeach(Map map);

2、编写SQL语句

<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、测试

@Test
public void testQueryBlogForeach(){SqlSession session = MybatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap map = new HashMap();List<Integer> ids = new ArrayList<Integer>();ids.add(1);ids.add(2);ids.add(3);map.put("ids",ids);List<Blog> blogs = mapper.queryBlogForeach(map);System.out.println(blogs);session.close();
}

小结:其实动态 sql 语句的编写往往就是一个拼接的问题,为了保证拼接准确,我们最好首先要写原生的 sql 语句出来,然后在通过 mybatis 动态sql 对照着改,防止出错。

MyBatis学习总结-06:动态SQL相关推荐

  1. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)--动态SQL 转载于:https://www.cnblogs.com/MrSaver/p/7453949.html

  2. mybatis学习7之动态sql

    动态sql环境搭建和数据准备 工具类,获取UUID package com.shan.utils;import org.junit.Test;import java.util.UUID;public ...

  3. Mybatis学习笔记之---动态sql中标签的使用

    动态Sql语句中标签的使用 (一)常用标签 1.<if> if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于UPDATE语句中判断是否更新某一个字段 ...

  4. Mybatis学习笔记13 - 动态sql之set标签

    示例代码: 接口定义: package com.mybatis.dao;import com.mybatis.bean.Employee;public interface EmployeeMapper ...

  5. 【Java从0到架构师】MyBatis - 增删改、动态 SQL

    MyBatis - 增删改.动态 SQL 动态 SQL if 标签 where 标签 sql 标签 foreach 标签 添加 主键设置 批量添加 - 利用 foreach 标签 更新 删除 批量删除 ...

  6. JavaWeb学习笔记(动态SQL)

    JavaWeb学习笔记(动态SQL) 动态SQL中的元素 < if>元素 < choose>.< when>.< otherwise>元素 < w ...

  7. Java神鬼莫测之MyBatis注解开发之动态SQL语句(六)

    1.Mybatis注解开发之动态SQL语句 背景:使用mybatis的注解开发动态Sql会比较麻烦, 很不方便, 所以不太推荐使用,该文章以查询作为案例,演示动态sql语句. 注意:Mybatis的动 ...

  8. SSM框架开发web项目系列(四) MyBatis之快速掌握动态SQL

    前言 通过前面的MyBatis部分学习,已经可以使用MyBatis独立构建一个数据库程序,基本的增删查改/关联查询等等都可以实现了.简单的单表操作和关联查询在实际开的业务流程中一定会有,但是可能只会占 ...

  9. Mybatis框架(复杂动态SQL),一对一,一对多,多对多

    复合条件查询(动态SQL) MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记 ...

  10. Mybatis系列全解(八):Mybatis的9大动态SQL标签你知道几个?提前致女神!

    封面:洛小汐 作者:潘潘 2021年,仰望天空,脚踏实地. 这算是春节后首篇 Mybatis 文了~ 跨了个年感觉写了有半个世纪 - 借着女神节 ヾ(◍°∇°◍)ノ゙ 提前祝男神女神们越靓越富越嗨森! ...

最新文章

  1. 京东涉足快递业加剧行业动乱
  2. 物联网浪潮即将来袭,创业者们你需要知道这些
  3. Java 基础 - 各项集合实现
  4. Python实现比较两个列表(list)范围
  5. 58岁博导为88岁老母跳舞,“母亲眼里我永远是个孩子”
  6. java地图源码_Java集合源码分析(四)HashMap
  7. 如何优化cocos2d/x程序的内存使用和程序大小
  8. php抓娃娃机器,vue制作抓娃娃机 - osc_icwhzig7的个人空间 - OSCHINA - 中文开源技术交流社区...
  9. js常用的加密/解密方法
  10. android 取色器
  11. 第三次科技革命(一)
  12. 用html制作一个中国高铁网页,行者|终于有人制作了一张靠谱的全国高铁地图!...
  13. GPS测量中涉及的坐标系
  14. Flexbox在button/fieldset/legend中(比如safair)失效问题
  15. 【理论篇】IC间通信的时序模型——系统同步、源同步和自同步
  16. 北京上市公司招聘.net架构师及开发人员
  17. sen1.2词典制作
  18. 中国石油大学《中国当代散文》共享课程考试
  19. 20210514面试题自我分类及总结(一)
  20. 解决SecureFX中文乱码的方法

热门文章

  1. 关于ThinkPad T490s 风扇不转动问题
  2. 中南林业科技大学的计算机研究生分数线,2020中南林业科技大学研究生分数线(以及历年复试)...
  3. [CF1504E]Travelling Salesman Problem
  4. 汽车厂VIN码生成软件
  5. GPT-3写了一篇论文
  6. 制造上云 佛山南海携手阿里云建创新中心
  7. 基于自适应参数及小生境的改进鲸鱼优化算法
  8. 主、谓、宾、定、状、补
  9. ctfshow web78-web81文件包含漏洞 wp
  10. python嵌入java,java架构如何嵌入python?Java调用Python程序方法