MyBatis学习(三)MyBatis的动态SQL

动态SQL

1、动态Sql简介

Mybatis官方文档

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
2、使用动态SQL开发

数据库:

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.zyh.pojo;

import lombok.Data;

import java.util.Date;
@Data
public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createime;
    private int views;
}

实体类对应的接口:

package com.zyh.mapping;

import com.zyh.pojo.Blog;

public interface BlogMapper {

    /**
     * 插入数据
     * @param blog
     * @return
     */
    int addBlog(Blog blog);

}

接口的BlogMapper.xml配置


        
        
<mapper namespace="com.zyh.mapping.BlogMapper">

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

测试:新增博客

package com.zyh.mapping;

import com.zyh.pojo.Blog;
import com.zyh.utils.IDUtils;
import com.zyh.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;

import java.util.Date;


public class BlogMapperTest {
    @Test
    public void test(){
        SqlSession session = MyBatisUtils.getSession(true);
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        //新增博客
        for (int i = 1; i <= 10; i++) {
            Blog blog = new Blog();
            blog.setId(IDUtils.getId());
            blog.setTitle("Mybatis"+i);
            blog.setAuthor("zyh");
            blog.setCreateTime(new Date());
            blog.setViews(399);
            mapper.addBlog(blog);
        }

        session.close();

    }
}

执行结果:
MyBatis学习(三)MyBatis的动态SQL_第1张图片

MyBatis学习(三)MyBatis的动态SQL_第2张图片
案例1:if

通过作者名字和博客名字来查询博客
如果作者的名字为空,就根据博客名字来查询

接口新增方法:

package com.zyh.mapping;

import com.zyh.pojo.Blog;

import java.util.List;
import java.util.Map;

public interface BlogMapper {

    /**
     * 插入数据
     */
    int addBlog(Blog blog);

    /**
     * > 通过作者名字和博客名字来查询博客
     * > 如果作者的名字为空,就根据博客名字来查询
     *  如果不知道参数有几个,就使用Map进行传参
     */
     List<Blog> getBlogByIf(Map map);
}

BlogMapper.xml 中的新增配置:

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

测试:

    @Test
    public void testgetBlogByIf(){
        SqlSession session = MyBatisUtils.getSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);

        Map<String, String> map = new HashMap<String, String>();
        map.put("title","Mybatis1");
        map.put("author","zyh");
        List<Blog> blogs = mapper.getBlogByIf(map);
        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        session.close();
    }

执行结果:
MyBatis学习(三)MyBatis的动态SQL_第3张图片
案例2:where 如果测试时给这个方法传递的参数是一个空 map ,会发生什么呢?

测试:

    @Test
    public void testgetBlogByIf(){
        SqlSession session = MyBatisUtils.getSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);

        Map<String, String> map = new HashMap<String, String>();
//        map.put("title","Mybatis1");
//        map.put("author","zyh");
        List<Blog> blogs = mapper.getBlogByIf(map);
        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        session.close();
    }
}

MyBatis学习(三)MyBatis的动态SQL_第4张图片
我们可以看到 Sql 语句报错,SQL: select * from mybatis.blog where ,如果参数为空,后面的where语句的条件就为空,所以报错。

解决办法:where判断条件时可以使用动态SQL 标签,如果后面的条件为空,就可以自动去掉这个 where,而且在where 标签中,如果where后的条件是以or 或 and 开头,会自动去掉这个关键字。

xml中的sql语句:

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

MyBatis学习(三)MyBatis的动态SQL_第5张图片

案例3:set 如果后面的条件满足,它就会自动拼接 set 标签,后面如果有多余的,就会自动去掉。

接口:

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

xmlSQL配置

    <update 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}
    update>

测试:

    @Test
    public void testUpdateBlog(){
        SqlSession session = MyBatisUtils.getSession(true);
        BlogMapper mapper = session.getMapper(BlogMapper.class);

        Map<String,String> map = new HashMap<String, String>();
        map.put("id","33889a4a983e43cbb6a4acf47cc64a86");
        map.put("author","hang");
        map.put("title","Spring");
        mapper.updateBlog(map);

        session.close();
    }

执行结果:
MyBatis学习(三)MyBatis的动态SQL_第6张图片

如果我们只传递一个title参数,那么title=#{title}, 后面的逗号怎么办呢?set就可以用来处理这个问题,会自动去掉这个逗号。

测试:

    @Test
    public void testUpdateBlog(){
        SqlSession session = MyBatisUtils.getSession(true);
        BlogMapper mapper = session.getMapper(BlogMapper.class);

        Map<String,String> map = new HashMap<String, String>();
        map.put("id","33889a4a983e43cbb6a4acf47cc64a86");
        map.put("title","SpringMVC");
        mapper.updateBlog(map);

        session.close();
    }

MyBatis学习(三)MyBatis的动态SQL_第7张图片

案例4: choose 类似于Java 中的Switch

接口:

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

xml中的SQL:

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

测试:

第一次 :参数为空

    @Test
    public void testQueryBlogByChoose(){
        SqlSession session = MyBatisUtils.getSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        Map<String,String> map = new HashMap<String, String>();
        List<Blog> blogs = mapper.queryBlogByChoose(map);

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

执行结果:
MyBatis学习(三)MyBatis的动态SQL_第8张图片
第二次:参数为author

    @Test
    public void testQueryBlogByChoose(){
        SqlSession session = MyBatisUtils.getSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        Map<String,String> map = new HashMap<String, String>();
        map.put("author","hang");
        List<Blog> blogs = mapper.queryBlogByChoose(map);

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

MyBatis学习(三)MyBatis的动态SQL_第9张图片
第三次:参数为title

    @Test
    public void testQueryBlogByChoose(){
        SqlSession session = MyBatisUtils.getSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        Map<String,String> map = new HashMap<String, String>();
        map.put("title","Mybatis3");

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

MyBatis学习(三)MyBatis的动态SQL_第10张图片
第四次:参数为title + author

    @Test
    public void testQueryBlogByChoose(){
        SqlSession session = MyBatisUtils.getSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        Map<String,String> map = new HashMap<String, String>();
        map.put("title","SpringMVC");
        map.put("author","hang");
        List<Blog> blogs = mapper.queryBlogByChoose(map);

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

在这里插入图片描述

你可能感兴趣的:(MyBatis)