MyBatis学习笔记14 —— 动态 SQL常用标签

MyBatis学习笔记14 —— 动态 SQL常用标签


参考教程B站狂神https://www.bilibili.com/video/BV1NE411Q7Nx


什么是动态SQL

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

数据库表对应的实体类

package com.ylw.pojo;

import java.util.Date;

public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime; //属性名和字段名不一致,可以在配置文件里设置转换
    private int views;

    public Blog() {
    }

    public Blog(String id, String title, String author, Date createTime, int views) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.createTime = createTime;
        this.views = views;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public int getViews() {
        return views;
    }

    public void setViews(int views) {
        this.views = views;
    }

    @Override
    public String toString() {
        return "Blog{" +
                "id='" + id + '\'' +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", createTime=" + createTime +
                ", views=" + views +
                '}';
    }
}

用来随机生成ID的工具类

package com.ylw.utils;

import org.junit.Test;

import java.util.UUID;

public class IDUtils {

    public static String getId(){
        //随机生成id,并把-替换成空
        return UUID.randomUUID().toString().replaceAll("-","");
    }

    @Test
    public void test(){
        System.out.println(IDUtils.getId());
    }
}

MyBatis核心配置文件

设置开启驼峰命名转换规则

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

if

接口

    //查询博客
    List<Blog> queryBlogIf(Map map);

Mapper.xml配置文件

    <!--这里写where是为了便于后面的if拼接,并且当if都不符合的时候也可以确保查询语句正确,还可以写where标签-->
    <select id="queryBlogIf" parameterType="map" resultType="com.ylw.pojo.Blog">
        select * from mybatis.blog where 1=1
        <if test="title != null">
            and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </select>

测试类

    @Test
    public void queryBlogIf(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();
        map.put("title","Java如此简单");

        List<Blog> blogs = mapper.queryBlogIf(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }

        sqlSession.close();
    }

where标签

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

把上面的where 1=1语句改成下面的where标签

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

choose (when, otherwise)

choose标签里有when和otherwise
可以理解为
switch语句里的case和default,
先执行符合条件的when,没有就执行otherwise(注意只会执行一个when)

接口

    List<Blog> queryBlogChoose(Map map);

Mapper.xml配置文件

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

测试

    @Test
    public void queryBlogIf(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();
        map.put("title","java如此简单"); //这里由于choose语句只会执行第一个when
        map.put("author","狂神说");
        map.put("views",9999);

        List<Blog> blogs = mapper.queryBlogChoose(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }

        sqlSession.close();
    }

set标签

set去除逗号
MyBatis学习笔记14 —— 动态 SQL常用标签_第1张图片

sql标签

有的时候,我们可能会将一些功能的部分抽取出来,方便复用!

  1. 使用SQL标签抽取公共的部分

    <sql id="if-title-author">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </sql>
    
  2. 在需要使用的地方使用Include标签引用即可

    <select id="queryBlogIF" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <where>
            <include refid="if-title-author"></include>
        </where>
    </select>
    

注意事项:

  • 最好基于单表来定义SQL片段!
  • sql标签里不要存在where标签

你可能感兴趣的:(JavaWeb基础和SSM框架)