Mybatis 札记(五、动态SQL)麻雀虽小,五脏俱全

一:动态SQL 概念

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

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

  • if

    提供了可选的查找文本功能

  • choose (when, otherwise) 从多个条件中选择一个使用

    传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG

  • trim (where, set)

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

    set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

  • foreach

二:动态SQL 环境搭建

1、新建模块 (导入依赖)

    <dependencies>
<!-- Lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>

2、编写配置文件

在这里插入图片描述

3、新建数据库表

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

4、编写实体类

import lombok.Data;
import java.util.Date;
@Data
public class Blog {
    private String id;          //博客id
    private String title;       //博客标题
    private String author;      //博客作者
    private Date createTime;    //创建时间
    // 属性名和字段名不一致  开启驼峰命名映射 在核心配置文件中配置mapUnderscoreToCamelCase
    private int views;          //浏览量
}

5、编写实体类对应的Mapper接口 和 Mapper.xml文件

Mapper接口

public interface BlogMapper {
}

Mapper.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.csnz.dao.BlogMapper">

</mapper>

6、在mybatis核心配置文件中对Mapper进行注册

在这里插入图片描述

7、新建一个随机生成id的工具类

import java.util.UUID;

public class IDUtils {
    public static String getId(){
        return UUID.randomUUID().toString().replace("-","");
    }
}

8、目前数据库表中无数据 插入数据

在这里插入图片描述
最后新建一个测试类测试一波~

public class TestBlog {
    @Test
    public void testInsert(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blog = new Blog();
        blog.setId(IDUtils.getId());
        blog.setTitle("潮汕奴仔学Mybatis");
        blog.setAuthor("潮汕奴仔");
        blog.setCreateTime(new Date());
        blog.setViews(666);

        mapper.add(blog);
        sqlSession.close();
    }
}

在这里插入图片描述
接下来大家可以照猫画虎多插几条数据进去

三、尝试编写动态SQL

1、If

在这里插入图片描述

<!--根据条件查询-->
    <select id="queryByIf" parameterType="map" resultType="blog">
        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 testIf(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap();
//        map.put("title","潮汕奴仔学Mybatis");
        map.put("author","CSNZ");
        List<Blog> blogs = mapper.queryByIf(map);
        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

在这里插入图片描述

2、trim ( where、set )

where

<!--根据条件查询  if  -->
    <select id="queryByIf" 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>

set

在这里插入图片描述
在这里插入图片描述

<!--根据条件 更新 set-->
    <update id="updateBySet" parameterType="map">
        update blog
        <set>
            <if test="title != null">
                title = #{title},
            </if>
            <if test="author != null">
                author = #{author}
            </if>
        </set>
        where id = #{id}
    </update>

对应的测试demo

@Test
    public void testUpdateSet(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap();
//        map.put("title","奴仔学Vue");
        map.put("author","HaibaraAi");
        map.put("id","830344215782422b89dfdfd2cac008b2");
        mapper.updateBySet(map);
        sqlSession.close();
    }

3、choose ( when , otherwise )

在这里插入图片描述

<!--根据条件查询  choose-->
    <select id="queryByChoose" 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>

对应的测试demo

    @Test
    public void testChoose(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap();
        map.put("title","潮汕奴仔学Vue");
        map.put("author","CSNZ");
        map.put("views",1000);
        List<Blog> blogs = mapper.queryByChoose(map);
        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

总结:

动态SQL的实质还是一个SQL ,只是我们可以 在编写 sql 时,执行逻辑判断

四:SQL片段

思想:封装代码 ,方便复用

1、使用sql 标签抽取公共的部分

<!--SQL片段-->
    <sql id="if-title-author">
        <if test="title != null">
            title = #{title},
        </if>
        <if test="author != null">
            author = #{author}
        </if>
    </sql>

2、在需要使用的地方使用include标签引用

在这里插入图片描述
在这里插入图片描述

注意事项:

  • 最好基于单表来定义SQL片段

  • 不要存在where标签

五:foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候

官网案例

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

foreach 元素的功能:

指定一个集合,可以在元素体内使用的集合项(item)和索引(index)变量。

它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。

下面开始编写测试代码

在这里插入图片描述
在这里插入图片描述

先测试空的集合 会发生肾么丝!

 @Test
    public void testForEach(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        ArrayList ids = new ArrayList();

        Map map = new HashMap();
        map.put("ids",ids);
        mapper.getBlogsByForEach(map);
        sqlSession.close();
    }
亚巴里~ 查询了全部

在这里插入图片描述

接下来我们给ids集合添加元素试试
 @Test
    public void testForEach(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        ArrayList ids = new ArrayList();
        ids.add("0d1df68b89604b4d9c8ca0233d4dc20e");
        ids.add("95d317d5401e44c8bbba8cb07a3a2d41");
        ids.add("1d4a10e260264050a77e810d0bd2e11c");
        Map map = new HashMap();
        map.put("ids",ids);
        mapper.getBlogsByForEach(map);
        sqlSession.close();
    }

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值