什么是动态SQL:动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.
我们之前写的 SQL 语句都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。
那么怎么去解决这个问题呢?这就要使用 mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。
元素:
ifchoose (when, otherwise)trim (where, set)foreach新建一个数据库表:blog 字段:id,title,author,create_time,views
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创建Mybatis基础工程
IDutil工具类
public class IDUtil { //生成随机的ID public static String genId(){ return UUID.randomUUID().toString().replaceAll("-",""); } } 实体类编写 【注意set方法作用】 import java.util.Date; @Data public class Blog { private String id; private String title; private String author; private Date createTime; private int views; } 编写Mapper接口及xml文件 public interface BlogMapper { } <?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="com.kuang.mapper.BlogMapper"> </mapper> mybatis核心配置文件,下划线驼峰自动转换 <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <!--注册Mapper.xml--> <mappers> <mapper resource="mapper/BlogMapper.xml"/> </mappers> 插入初始数据 编写接口//新增一个博客 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(); } 初始化数据完毕!编写接口类
//需求1 List<Blog> queryBlogIf(Map map);编写SQL语句
<!--需求1: 根据作者名字和博客名字来查询博客! 如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询 select * from blog where title = #{title} and author = #{author} --> <select id="queryBlogIf" parameterType="map" resultType="blog"> <!-- 这里用 1=1 占了第一个筛选条件的位置,这样后面的每一句话的 and 就不会报错 --> select * from blog where 1=1 <if test="title != null"> and title = #{title} </if> <if test="author != null"> and author = #{author} </if> </select>测试
@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(); }修改上面的SQL语句
<select id="queryBlogIf" parameterType="map" resultType="blog"> select * from blog <!-- 使用 where 标签就不需要加上 1=1 的条件占位,where 会自动的删除多余的 and --> <where> <if test="title != null"> title = #{title} </if> <if test="author != null"> and author = #{author} </if> </where> </select> 这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。