文章目录

  • 1. 简介
  • 2. 搭建环境
    • 2.1 在MySQL中创建blog表
    • 2.2 编写实体类
    • 2.3 编写实体类对应Mapper接口
    • 2.4 编写Mapper接口对应的Mapper.xml文件
    • 2.5 编写测试类
  • 3. if
  • 4. where
  • 5. set
  • 6. choose
  • 7. foreach

1. 简介

动态SQL就是指根据不同的条件生成不同的SQL语句

传统的使用JDBC的方法,在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。

2. 搭建环境

2.1 在MySQL中创建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.2 编写实体类

package com.zz.pojo;import lombok.Data;import java.util.Date;@Data
public class Blog {private String id;private String title;private String author;private Date createDate;private int views;}

可选择在idea中连接数据库

解决办法:在mybatis-config.xml中开启驼峰命名
同时也开启日志

<!--开启日志和驼峰命名--><settings><setting name="mapUnderscoreToCamelCase" value="true"/><setting name="logImpl" value="STDOUT_LOGGING"/></settings>

2.3 编写实体类对应Mapper接口

package com.zz.mapper;import com.zz.pojo.Blog;public interface BlogMapper {//新增一个博客int addBlog(Blog blog);
}

2.4 编写Mapper接口对应的Mapper.xml文件

<?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.zz.mapper.BlogMapper"><insert id="addBlog" parameterType="Blog">insert into mybatis.blog (id, title, author, create_time, views)values (#{id},#{title},#{author},#{createDate},#{views});
</insert></mapper>

2.5 编写测试类

可选择在util目录下创建IDUtils工具类,因为在真实开发中id一般是随机的数字,调用IDUtils类,保证生成的id都不相同。

package com.zz.utils;import java.util.UUID;public class IDUtils {public static String getId(){return UUID.randomUUID().toString().replaceAll("-","");}
}

编写测试类,往数据库中添加八篇博客

package com.zz.mapper;import com.zz.pojo.Blog;
import com.zz.utils.IDUtils;
import com.zz.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.Date;public class BlogMapperTest {@Testpublic void testAddBlog(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Blog blog01 = new Blog();//调用IDUtils包,保证id都不相同blog01.setId(IDUtils.getId());  //真实开发中id一般是随机的数字(uuid)blog01.setTitle("Hello MyBatis");blog01.setAuthor("大佬");blog01.setCreateDate(new Date());blog01.setViews(9999);mapper.addBlog(blog01);Blog blog02 = new Blog();//调用IDUtils包,保证id都不相同blog02.setId(IDUtils.getId());  //真实开发中id一般是随机的数字(uuid)blog02.setTitle("Hello JDBC");blog02.setAuthor("大佬");blog02.setCreateDate(new Date());blog02.setViews(9999);mapper.addBlog(blog02);Blog blog03 = new Blog();//调用IDUtils包,保证id都不相同blog03.setId(IDUtils.getId());  //真实开发中id一般是随机的数字(uuid)blog03.setTitle("Hello MySQL");blog03.setAuthor("大佬");blog03.setCreateDate(new Date());blog03.setViews(9999);mapper.addBlog(blog03);Blog blog04 = new Blog();//调用IDUtils类,保证id都不相同blog04.setId(IDUtils.getId());  //真实开发中id一般是随机的数字(uuid)blog04.setTitle("Hello Spring");blog04.setAuthor("大佬");blog04.setCreateDate(new Date());blog04.setViews(9999);mapper.addBlog(blog04);session.commit(); //提交事务}
}

运行结果:

至此,环境搭建完毕!

3. if

接口BlogMapper的代码:

package com.zz.mapper;import com.zz.pojo.Blog;import java.util.List;
import java.util.Map;public interface BlogMapper {//新增一个博客int addBlog(Blog blog);//通过作者名和博客名来查询博客//如果作者名为空,则根据博客名来查询List<Blog> getBlogByIf(Map map);
}

接口的配置文件BlogMapper.xml 代码:

<?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.zz.mapper.BlogMapper"><insert id="addBlog" parameterType="Blog">insert into mybatis.blog (id, title, author, create_time, views)values (#{id},#{title},#{author},#{createDate},#{views});
</insert><select id="getBlogByIf" resultType="Blog" parameterType="map">select * from mybatis.blog where<if test="title!=null">title=#{title}</if><if test="author!=null">and author=#{author}</if></select></mapper>

测试类BlogMapperTest 代码:

  • 当在map中只添加title时
public class BlogMapperTest {//测试if@Testpublic void testGetBlogByIf(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Map<String, String> map = new HashMap<String, String>();map.put("title","Hello MyBatis");//map.put("author","小白");List<Blog> blogByIf = mapper.getBlogByIf(map);for (Blog blog : blogByIf) {System.out.println(blog);}}
}

运行结果:

  • 当在map中添加title和author时
public class BlogMapperTest {//测试if@Testpublic void testGetBlogByIf(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Map<String, String> map = new HashMap<String, String>();map.put("title","Hello MyBatis");map.put("author","小白");List<Blog> blogByIf = mapper.getBlogByIf(map);for (Blog blog : blogByIf) {System.out.println(blog);}}
}

运行结果:

可以看出:根据不同的条件生成不同的SQL语句,即动态SQL

4. where

使用场景:如果我们需要拼接where条件,又不希望客户端传递错误信息,这时需要使用where 标签。
作用:如果后面有语句,就自动添加where;如果后面语句开头是and 或者or,它可以自动去掉。

接口的配置文件BlogMapper.xml 代码:
注意:在author 前添加了 and

<?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.zz.mapper.BlogMapper"><insert id="addBlog" parameterType="Blog">insert into mybatis.blog (id, title, author, create_time, views)values (#{id},#{title},#{author},#{createDate},#{views});
</insert><select id="getBlogByIf" resultType="Blog" parameterType="map">select * from mybatis.blog<where><if test="title!=null">title=#{title}</if><if test="author!=null">and author=#{author}</if></where></select></mapper>

测试类BlogMapperTest 的代码:

  • 当在map中什么都不添加,为空时
public class BlogMapperTest {//测试where@Testpublic void testGetBlogByIf(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Map<String, String> map = new HashMap<String, String>();//map.put("title","Hello MyBatis");//map.put("author","小白");List<Blog> blogByIf = mapper.getBlogByIf(map);for (Blog blog : blogByIf) {System.out.println(blog);}}
}

运行结果:

可以看出:查询出了所有的博客

  • 当在map中只添加author时
public class BlogMapperTest {//测试where@Testpublic void testGetBlogByIf(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Map<String, String> map = new HashMap<String, String>();//map.put("title","Hello MyBatis");map.put("author","小白");List<Blog> blogByIf = mapper.getBlogByIf(map);for (Blog blog : blogByIf) {System.out.println(blog);}}
}

运行结果:

可以看出,把配置文件中的 and 去掉了

5. set

如果里面的条件满足,自动拼接set标签;后面如果有多余的逗号,可以自动去除

接口BlogMapper的代码:

 //更新博客int updateBlog(Map map);

接口的配置文件BlogMapper.xml 代码:

注意:在title 后添加了逗号

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

测试类BlogMapperTest 的代码:

map中必须添加id,否则会报错

  • 当在map中只添加id和author时
//测试set@Testpublic void testSet(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("id","74205db5524c4e92942241e8b6443032");map.put("author","大佬");//map.put("title","大佬");mapper.updateBlog(map);session.commit();}

运行结果:

  • 当在map中添加id,author和title时
  //测试set@Testpublic void testSet(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("id","74205db5524c4e92942241e8b6443032");map.put("author","大佬");map.put("title","大佬");mapper.updateBlog(map);session.commit();}

运行结果:

  • 当在map中只添加id和title时
//测试set@Testpublic void testSet(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("id","74205db5524c4e92942241e8b6443032");//map.put("author","大佬");map.put("title","大佬");mapper.updateBlog(map);session.commit();}

运行结果:

可以发现:title 后面的逗号去掉了

where标签和set 标签的底层都是trim标签

6. choose

好比java中的switch

接口BlogMapper的代码:

//查询博客 但是只要有一个条件满足即可
List<Blog> queryBlogByChoose(Map map);

接口的配置文件BlogMapper.xml 代码:

<select id="queryBlogByChoose" parameterType="map" resultType="Blog">select * from mybatis.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>

测试类BlogMapperTest 的代码:

  • 当在map中什么都不添加时
//测试choose@Testpublic void testChoose(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();mapper.queryBlogByChoose(map);session.commit();}

运行结果:

  • 当在map中只添加title时
 //测试choose@Testpublic void testChoose(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("title","Hello Spring");mapper.queryBlogByChoose(map);session.commit();}

运行结果:

  • 当在map中只添加author时
 //测试choose@Testpublic void testChoose(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();//map.put("title","Hello Spring");map.put("author","大佬");mapper.queryBlogByChoose(map);session.commit();}

运行结果:

  • 当在map中添加title和author时
//测试choose@Testpublic void testChoose(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("title","Hello Spring");map.put("author","大佬");mapper.queryBlogByChoose(map);session.commit();}

运行结果:

可以看出:虽然传入了两个参数,但只显示了一个

7. foreach

相当于子查询 where in(1,2,3)

collection 表示输入的参数 map
item 表示遍历出来的每一项
open 表示打开
close 表示关闭
separator 表示分割符
通过item 遍历出来的标签可以在foreach中使用

接口BlogMapper的代码:

List<Blog> queryBlogByForeach(Map map);

接口的配置文件BlogMapper.xml 代码:

<!--子查询 where in(1,2,3)--><select id="queryBlogByForeach" parameterType="map" resultType="Blog">select * from mybatis.blog<where><foreach collection="ids" item="id" open="and (" close=")" separator="or">id = #{id}</foreach></where></select>

测试类BlogMapperTest 代码:

 //测试foreach@Testpublic void testForeach(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Map<String,List> map = new HashMap();List<String> ids = new ArrayList<String>();ids.add("bac368d88b4a4d8eb6bd1b539a3338a0");ids.add("321c98e9beea45d092c39b2cfe0fc370");ids.add("cfbc34f0a1dd40fdba91e99dfe4c365a");map.put("ids",ids);mapper.queryBlogByForeach(map);session.commit();}

运行结果:

可以看出:就相当于SQL中的 select * from mybatis.blog where and (id=xxx or id=xxx or id=xxx)

MyBatis(三)——动态SQL相关推荐

  1. MyBatis的动态SQL详解

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

  2. 9、mybatis中动态sql的使用

    对于初学者,如何进行mybatis的学习呢?我总结了几点,会慢慢的更新出来.首先大家需要了解mybatis是什么.用mybatis来做什么.为什么要用mybatis.有什么优缺点:当知道了为什么的时候 ...

  3. MyBatis 03 动态SQL

    MyBatis 03 动态SQL 文章目录 MyBatis 03 动态SQL 一.学习目标 二.动态SQL if 标签2-1 if 标签2-2 where标签2-1 where 标签2-2 choos ...

  4. Mybatis中动态sql小结

    这篇文章讲述的是Mybatis中动态sql小结,如有错误或不当之处,还望各位大神批评指正. 什么是动态sql MyBatis 的强大特性之一便是它的动态 SQL,它极大的简化了我们拼接SQL的操作. ...

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

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

  6. MyBatis中动态sql实现时间范围比较的查询

    场景 前端传递两个时间参数,开始时间和结束时间,然后从数据库中筛选出某个时间属性在此范围的数据. Mybatis的动态sql的写法. 注: 博客: https://blog.csdn.net/bada ...

  7. MyBatis中动态sql的模糊搜索、foreach实现In集合的用法

    场景 在使用MyBatis的动态sql时,常见的是传递一个ID的数组,查询记录的 ID在这个数组中的记录和模糊搜索这两种场景. 注: 博客: https://blog.csdn.net/badao_l ...

  8. mybatis的动态sql的一些记录

    动态sql的作用:传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误.Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if ...

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

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

最新文章

  1. 【C++】【四】企业链表
  2. msc货物跟踪查询_运联研究 | 货物全程可视,能否真正消除物流信息盲点?
  3. Matlab C++混合编程 在VisualStudio下的编程 使用了Opencv库
  4. 1.4编程基础之逻辑表达式与条件分支 11 晶晶赴约会
  5. Java语言跨平台性质的优点和缺点_机器人热门编程语言及优缺点分析
  6. Java 算法 最大体积
  7. python批量运行cmd_python 批量ssh并执行命令
  8. 从没见过干净图片,英伟达AI就学会了去噪大法 | ICML论文
  9. [py]py常用模块小结
  10. 【推荐】开源领袖陆首群力作:什么是数字经济?
  11. 阿里云云计算 48 云安全中心
  12. 安徽大学江淮学院计算机作业,安徽大学江淮学院
  13. 合并排序-MergeSort
  14. 算法4_对称加密算法之SM4
  15. 乾坤大挪移——使用PQ分区魔术师扩大C盘空间
  16. 闰年和平年的区别python_连续四年中一定有一个闰年吗
  17. 出差中,推荐几个百度,腾讯,抖音大佬的公众号
  18. CVPR2021目标检测方向论文
  19. 解决项目部署到阿里云服务器邮件发送失败的方法
  20. 再讲卷积的本质及物理意义,解释的真幽默!

热门文章

  1. 卷积核里面的参数怎么来的_FSNet:利用卷积核概要进行深度卷积神经网络的压缩...
  2. mac bash file密码_Mac系统 | 菜鸟程序员项目模拟数据迁移,会安装Mysql服务端吗
  3. android 活动说明,Android – 如何发送GCM推送通知以及要加载哪些活动的说明?
  4. python连接高斯数据库_Python加载数据并执行多高斯fi
  5. ADO winform注册
  6. Java 8 – Period and Duration examples
  7. python框架-Django安装使用
  8. shell脚本接收输入
  9. 前端性能优化:使用Data URI代替图片SRC
  10. 12家国内外之名公司多场面试,微软到谷歌.让我们通过学习达到100%面试率与100%通过率...