不能吧,你不能这样,都最后了-------sql和缓存(“最易懂得MyBatis学习”)(中)

简介: 4. trim(where,set)4.1 where4.2 set5. choose(when,otherwise)6. foreach使用7. SQL片段8. 总结

4. trim(where,set)

4.1 where

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

微信图片_20211230122330.png


  • where元素只会在至少有一个子元素的条件返回SQL子句的情况下采取插入“WHERE”自子句,而且,若语句的开头为“AND“或”OR“,where元素也会将它们去除。


  • 我们很容易看到,之前提到的if是用了一个where 1=1.其实这个是不合适的。但是现在加了个标签,它可以自动识别是不是第一个where,然后在判断是否加上and。


  • where的存在会判断and是不是需要,第二个前面及以后要加上and。


如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>


prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。


4.2 set


  • set元素会动态前置SET关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的SQL语句的后面留下这些逗号
<!--基本类型不需要resultType-->
<update id="updateBlog" parameterType="map">
  update blog
  <set>
      <if test="title != null">
          title = #{title},
      </if>
      <if test="author != null">
          author = #{author},
      </if>
  </set>
  where id = #{id}
</update>
@Test
public void updateBlog(){
  SqlSession sqlSession = MybatisUtils.getSqlSession();
  BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
  HashMap map = new HashMap();
  map.put("id","ac040b29e3b047a09a4fe78797193597");
  map.put("author","王木木");
  map.put("title","Java1");
  mapper.updateBlog(map);
  sqlSession.close();
}

来看看与 set 元素等价的自定义 trim 元素吧:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>


注意,我们覆盖了后缀值设置,并且自定义了前缀值。


5. choose(when,otherwise)

<select id="queryBlogChoose" parameterType="map" resultType="blog">
    select * from blog
    <where>
        <choose>
            <when test="title != null">
                title = #{title}
            </when>
            <when test="author != null">
                author = #{author}
            </when>
            <otherwise>
                and views = #{views}
            </otherwise>
        </choose>
    </where>
</select>
select * from user where 1=1 and
<foreach item="id" collection="ids"
  open="(" separator="or" close=")">
</foreach>
(id=1 or id=2 or id=3)

这个choose有点像switch,case。他只能运行一个。比如说前面的都不符合,那他必须有一个views要符合,否则会报错。前面的按照顺序有一个符合了,那他就跳出去了。


6. foreach


微信图片_20211230122650.png

select * from user where 1=1 and
<foreach item="id" collection="ids"
  open="(" separator="or" close=")">
</foreach>
(id=1 or id=2 or id=3)

使用

//查询第1-2-3号记录的博客
List<Blog> queryBlogForeach(Map map);
<!--传递一个万能的map,这个map可以存在一个集合-->
<select id="queryBlogForeach" parameterType="map" resultType="blog">
    select * from blog
    <where>
        <foreach item="id" collection="ids" open="and (" separator="or" close=")">
            id = #{id}
        </foreach>
    </where>
</select>
@Test
public void queryBlogForeach(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    //这里因为是uuid是String,如果是1,2这种就用Integer
    ArrayList<String> ids = new ArrayList<String>();
    map.put("ids",ids);
    List<Blog> blogs = mapper.queryBlogForeach(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

微信图片_20211230122807.png


我们还可以进行下面的测试

@Test
public void queryBlogForeach(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    ArrayList<String> ids = new ArrayList<String>();
    ids.add("ac040b29e3b047a09a4fe78797193597");
    map.put("ids",ids);
    List<Blog> blogs = mapper.queryBlogForeach(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

微信图片_20211230122842.png

@Test
public void queryBlogForeach(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    ArrayList<String> ids = new ArrayList<String>();
    ids.add("ac040b29e3b047a09a4fe78797193597");
    ids.add("a46a7874d69f4d69b9572816d8f30ab7");
    map.put("ids",ids);
    List<Blog> blogs = mapper.queryBlogForeach(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

微信图片_20211230122909.png


7. SQL片段


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


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


微信图片_20211230122946.png


2.在需要使用的地方使用include标签引用即可


我们可以加一个sql标签,id可以随意取,然后下面来一个include refid是引用id,和上面的id是一个。这样就可以实现复用。

<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 blog
    <where>
        <include refid="if-title-author"/>
    </where>
</select>


3.注意事项:


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


  • 不要存在where标签


8. 总结


所谓的动态SQL,本质还是SQL语句,只是我们可以在sql层面,去执行一个逻辑代码。

if,where,set,choose,when


动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就ok了


建议:


  • 先在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL。实现通用。


相关文章
|
2月前
|
缓存 Java 数据库连接
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
文章介绍了MyBatis的缓存机制,包括一级缓存和二级缓存的配置和使用,以及如何整合第三方缓存EHCache。详细解释了一级缓存的生命周期、二级缓存的开启条件和配置属性,以及如何通过ehcache.xml配置文件和logback.xml日志配置文件来实现EHCache的整合。
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
|
3天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
19天前
|
缓存 Java 数据库连接
使用MyBatis缓存的简单案例
MyBatis 是一种流行的持久层框架,支持自定义 SQL 执行、映射及复杂查询。本文介绍了如何在 Spring Boot 项目中集成 MyBatis 并实现一级和二级缓存,以提高查询性能,减少数据库访问。通过具体的电商系统案例,详细讲解了项目搭建、缓存配置、实体类创建、Mapper 编写、Service 层实现及缓存测试等步骤。
|
26天前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
30 10
|
25天前
|
SQL 缓存 Java
JVM知识体系学习三:class文件初始化过程、硬件层数据一致性(硬件层)、缓存行、指令乱序执行问题、如何保证不乱序(volatile等)
这篇文章详细介绍了JVM中类文件的初始化过程、硬件层面的数据一致性问题、缓存行和伪共享、指令乱序执行问题,以及如何通过`volatile`关键字和`synchronized`关键字来保证数据的有序性和可见性。
22 3
|
2月前
|
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标签的用法
|
25天前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
42 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
27天前
|
SQL 存储 数据库
SQL学习一:ACID四个特性,CURD基本操作,常用关键字,常用聚合函数,五个约束,综合题
这篇文章是关于SQL基础知识的全面介绍,包括ACID特性、CURD操作、常用关键字、聚合函数、约束以及索引的创建和使用,并通过综合题目来巩固学习。
27 1
|
2月前
|
Java 关系型数据库 数据库连接
mybatis-plus学习
MyBatis-Plus ,MyBatis 最佳搭档,只做增强不做改变,为简化开发、提高效率而生。
44 5
|
3月前
|
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/