【Mybatis系列】动态SQL

一、动态SQL

动态SQL:根据用户输入的不同查询条件,生成的不同SQL语句,之前咱们用的静态SQL,需要查询的条件几乎都是给定的,动态SQL语句功能是mybatis强大特性之一,当然JDBC也可以完成类似功能,只不过需要进行大量的SQL语句的拼接,会非常的麻烦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
 
动态SQL的本质:其实就是在原来的SQL语句的基础上增加的一些逻辑而已。
 

二、环境搭建

1、创建基础工程和数据库

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、工具类

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

3、实体类

@Data
public class Blog {
  private String id;
  private String title;
  private String author;
  private Date createTime;
  private int views;
}
 

4、Mapper接口和xml文件

public interface BlogMapper  {
  //查询博客
  List<Blog> queryBlogIf(Map map);
}

//xml文件
<?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.jason.dao.BlogMapper">
 
</mapper>

5、核心配置文件

<!--标准日志输出配置-->
<settings>
    <!--标准日志工厂的实现-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    <!--开启驼峰命名转换-->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<mappers>
    <mapper class="com.jason.dao.BlogMapper"/>
</mappers>

三、动态SQL详情:if+where

需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
 

1、不使用动态SQL写法:由于该select语句用and连接,只要title和author中有一个为空,那么整个查询结果就是空。显然不是我们想要的结果

<select id="queryBlogIf" parameterType="map" resultType="Blog">
    select * from mybatis.blog title = #{title} and author = #{author}
</select>

2、使用if进行判断:

如果author为空,则select * from mybatis.blog title = #{title},但是title为空呢?则select * from mybatis.blog and author = #{author},这个显然是一个错误的SQL语句,当然这也不是我们想要的结果。

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

      <if test="author != null">
          and author = #{author}
      </if>
</select>

3、动态SQL语句:

if+where语句,关键点在于where标签他可以去掉and。author为空则select * from mybatis.blog title = #{title};如果title为空则select * from mybatis.blog author = #{author},这样显然符合我们的要求。

<select id="queryBlogIf" 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>

4、他的强大不仅仅如此,如果我们在条件中既需要title又需要author,这是他会只能的将我的and添加上。

select * from mybatis.blog title = #{title} and author = #{author};当然如果我们两个条件都不要,他会只能的帮助我将where条件都去掉。

<select id="queryBlogIf" 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>

四、动态SQL详情:choose(where,when,otherwise)

我们不是在任何时候都要查询所有的条件,很多时候我们只想查任意一个条件,使用choose标签可以完成该任务,跟switch类似。具体:当三个条件都满足的时候,他也只会走第一个when分支;当第一个条件不满足,他会选择走第二个when分支;如果前面连个条件都不满足,他会选择走otherwise分支。这就是mybatis动态SQL的强大。
<select id="queryBlogChoose" 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>

五、动态SQL详情:set+if语句

这里主要针对的是更新语句问题,我们需要使用set语句进行处理
<update id="updateBlog" parameterType="Blog">
    update mybatis.blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="author != null">
            author = #{author}
        </if>
    </set>
    where id = #{id}
</update>

六、SQL片段:

其实就是将出现频率很高的代码,提取出来,简化代码,在使用的时候直接进行调用就可以。
<!--SQL片段-->
<sql id="if-title-author">
    <if test="title != null">
        title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</sql>

<select id="queryBlogIf" parameterType="map" resultType="Blog">
    select * from mybatis.blog
    <where>
        <!--导入SQL片段id即可-->
        <include refid="if-title-author"></include>
    </where>
</select>

七、动态SQL详情:trim的使用

trim其实就是一个格式化标记,可以完成set或where标记的功能,他可以去掉and、or、,等,下面实例中使用where和trim是一样的效果。
<select id="queryBlogIf" parameterType="map" resultType="Blog">
    select * from mybatis.blog
    <!--<where>
        <include refid="if-title-author"></include>
    </where>-->
    <trim prefix="where" prefixOverrides="and | or">
        <include refid="if-title-author"></include>
    </trim>
</select>

八、动态SQL详情:foreach的使用

Mapper.xml
<select id="queryBlogForeach" parameterType="map"
        resultType="Blog">
    select * from mybatis.blog
    <where>
        <foreach collection="ids" item="id" open="and (" close=")"
                 separator="or">
            id = #{id}
        </foreach>
    </where>
</select>

测试

@Test
public void queryBlogForeach(){
  SqlSession sqlSession = MybatisUtils.getSqlSession();
  BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
  HashMap hashMap = new HashMap();
  ArrayList<Integer> ids = new ArrayList<>();
  ids.add(1);
  ids.add(2);
  ids.add(3);
  hashMap.put("ids", ids);
  List<Blog> blogs = mapper.queryBlogForeach(hashMap);
  System.out.println(blogs);
  sqlSession.close();
}

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术蜗牛-阿春

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值