Mybatis第五篇| 这个sql,它会动!

简介: Mybatis第五篇| 这个sql,它会动!

目录

1.Mybatis第一篇|我的第一个Mybatis程序

2.Mybatis第二篇| CRUD,这才是程序员入门第一课

3.Mybatis第三篇| Mybatis配置,有点小个性!

4.Mybatis第四篇| 类处理器什么玩意?举个栗子你就知道了


前言

今天我们来学习一下动态sql,看起来很NB的感觉。我们来看看官网是怎么来介绍动态sql的。


5.png


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

简而言之,就是可以根据不同的条件自动给我们生产sql语句。废话不多说,我们看看到底是怎么操作的。


动态sql

虽然官方文档说这个特性很牛逼,但是还有一句话我们没看到:


5.jpg


使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

也就是说我们还是需要去学习动态sql语句的语法。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

动态语句其实也就上面的四个标签语句,用过xml的或者JSTL等文本处理语言的同学可能很快就能理解。

我们这次来重新创建一个SQL表,来进行我们这次的演示,建表语句放在下面:


CREATE TABLE `bolg`(
 `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


大家可以自己插入几条数据,下面是我在该表插入的数据:


1.png


if

首先在dao层创建我们的BlogMapper接口类:


public interface BlogMapper {
    List<Blog> queryBlogIF(Map map);
    List<Blog> queryBlogWhere(Map map);
    List<Blog> queryBlogChoose(Map map);
    int updateBlog(Map map);
    List<Blog> queryBlogForeach(Map map);
}


创建以上几个接口。

首先我们来看下if语句是怎么玩的:


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


if的语法就是


<if test="判断条件">
</if>


上面的判断条件就是如果title不等于null,那么就根据title来查询,如果author不等于null,那么就根据author来查询,如果两者都不等于null,那么就根据他们两者来进行查询。

我们再test中写一个简单的测试类:


@Test
public void queryBlogIF(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    map.put("title","编程如此简单2");
    map.put("author","kuls");
    List<Blog> blogs = mapper.queryBlogIF(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}


查询出来的结果


2.png


where


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


大家可能看到我在上面的where语句中含有 1=1 ,原因是如果我们不写一个where语句在前面,这条sql就会变成这样


select * from blog where and title = #{title}


这明显是错误的,当然1=1的写法也并不是很好,那怎么解决这个问题呢?mybatis也提供了一个< where >标签给我们使用。

我们将上面的语句改成下面的即可:


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


我们通过一个简单的测试类来看看他的运行结果:


@Test
public void queryBlogWhere(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    map.put("title","编程如此简单2");
    List<Blog> blogs = mapper.queryBlogWhere(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}


我们可以看到,通过where标签拼接成的语句变成了一条完整的sql语句(这里能够显示完整的sql语句是因为我使用了日志功能,这个功能我会在下一篇文章中介绍):


3.jpg


choose (when, otherwise)


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


还是回归到学习if时候的那句sql,如果我们有一个需求是满足title和author一个条件时就就够了情况时候,我们该怎么写呢?也就是从多个条件里我们只需要一个条件满足。mybatis也给我们提供了相应的标签:


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


其实这个语句跟我们的switch case语句非常相似,otherwise则是default。由于这个比较简单,我这里就不做演示了。


set

set语句也就比较简单了,直接上代码:


<update id="updateBlog" parameterType="map">
  update blog
  <set>
      <if test="title != null">
          title = #{title}
      </if>
      <if test="author != null">
          and author = #{author}
      </if>
  </set>
  where id = #{id}
</update>


set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。


trim

这个标签可能有一部分同学不太理解,其实where标签能够自动帮我们去除AND,就是依靠trim标签实现的。我们也可以直接使用trim的方式来实现where的效果:


<select id="queryBlogWhere" parameterType="map" resultType="blog">
select * from blog
<trim prefix="WHERE" prefixOverrides="AND">
    <if test="title != null">
        title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</trim>
</select>


使用trim,prefixOverrides 属性中指定的内容会被自动清除,然后填充为prefix中的内容。除了prefix前缀,我们也可以设置suffix后缀。


foreach

大家看名字应该大概理解是啥意思,其实就是对集合进行遍历的一个操作,例如我们根据一个id集合来查询相应id的内容。


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


大家先不用管理不理解上面的代码,我们先来进行测试:


@Test
public void queryBlogForeach(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    //创建一个id集合
    ArrayList<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(2);
    ids.add(3);
    map.put("ids",ids);
    //查询这个ids集合对应的内容
    List<Blog> blogs = mapper.queryBlogForeach(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}


我们输出时,可以看到日志中输出的内容


4.png


大家可以看到,mybatis给我们自动拼接了sql语句


select * from mybatis.blog WHERE ( id = ? or id = ? or id = ? )


这样的话,我们也就能过理解foreach中的属性了


<foreach collection="ids" item="id" open="(" close=")" separator="or">
    id = #{id}
</foreach>


  • collection是需要查询的集合
  • item集合中的每个属性
  • open 查询集合的前缀标签
  • close 查询集合的后缀标签
  • separator 分隔符


本文代码

完整代码:


https://github.com/hellokuls/kuls-mybatis


之后该系列的代码和文章全部放在这个GitHub项目,欢迎大家star!

相关文章
|
4月前
|
SQL Java 测试技术
3、Mybatis-Plus 自定义sql语句
这篇文章介绍了如何在Mybatis-Plus框架中使用自定义SQL语句进行数据库操作。内容包括文档结构、编写mapper文件、mapper.xml文件的解释说明、在mapper接口中定义方法、在mapper.xml文件中实现接口方法的SQL语句,以及如何在单元测试中测试自定义的SQL语句,并展示了测试结果。
3、Mybatis-Plus 自定义sql语句
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
21天前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
46 10
|
3月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
4月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
3月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
64 1
|
4月前
|
SQL Java 数据库连接
Mybatis系列之 动态SQL
文章详细介绍了Mybatis中的动态SQL用法,包括`<if>`、`<choose>`、`<when>`、`<otherwise>`、`<trim>`和`<foreach>`等元素的应用,并通过实际代码示例展示了如何根据不同条件动态生成SQL语句。
|
4月前
|
SQL 关系型数据库 MySQL
解决:Mybatis-plus向数据库插入数据的时候 报You have an error in your SQL syntax
该博客文章讨论了在使用Mybatis-Plus向数据库插入数据时遇到的一个常见问题:SQL语法错误。作者发现错误是由于数据库字段中使用了MySQL的关键字,导致SQL语句执行失败。解决方法是将这些关键字替换为其他字段名称,以避免语法错误。文章通过截图展示了具体的操作步骤。
|
4月前
|
SQL Java 关系型数据库
SpringBoot 系列之 MyBatis输出SQL日志
这篇文章介绍了如何在SpringBoot项目中通过MyBatis配置输出SQL日志,具体方法是在`application.yml`或`application.properties`中设置MyBatis的日志实现为`org.apache.ibatis.logging.stdout.StdOutImpl`来直接在控制台打印SQL日志。
SpringBoot 系列之 MyBatis输出SQL日志