Mybatis动态SQL实例详解

 更新时间:2020年11月12日 14:16:41   作者:IsDxh  
这篇文章主要给大家介绍了关于Mybatis动态SQL的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

动态SQL

什么是动态SQL?

MyBatis的官方文档中是这样介绍的?

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

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

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

换句话说,我们可以根据传入参数的不同,来执行不同的查询条件。

IF标签:

如何使用?

我们首先创建一个Mapper接口,起名为:UserMapper ,并增加一个方法

public interface UserMapper {
 public List<User> findByCondition(User user);
}

同时创建一个xml文件,起名为UserMapper.xml 然后编写SQL

<mapper namespace="com.dxh.dao.UserMapper">
 <select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User">
  SELECT * FROM user where 1=1
  <if test="id != null">
    and id = #{id}
   </if>
   <if test="username != null">
    and username = #{username}
   </if>
 </select>
</mapper>

这个SQL的意思是:

  • 当id不为null的时候执行的SQL是:SELECT * FROM user where id = #{id}
  • 当id为null的时候执行的SQL是 SELECT * FROM user where 1=1

很明显我们可以看到where 1=1 是多余的,因此我们可以这样写:

 <select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User">
  SELECT * FROM user 
  <where>
   <if test="id != null">
    and id = #{id}
   </if>
   <if test="username != null">
    and username = #{username}
   </if>
  </where>
 </select>

测试:

编写一个测试类:

package com.dxh.test;

import com.dxh.dao.UserMapper;
import com.dxh.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestMain {
 @Test
 public void test1() throws IOException {
  InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
  SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
  SqlSession sqlSession = build.openSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  User user = new User();
  user.setId(1);
  List<User> byCondition = mapper.findByCondition(user);
  for (User user1 : byCondition) {
   System.out.println(user1);
  }
  System.out.println("======");
  User user2 = new User();
  List<User> byCondition2 = mapper.findByCondition(user2);
  for (User user3 : byCondition2) {
   System.out.println(user3);
  }

 }
}

我们执行两次mapper.findByCondition() ,分别传入user和user2,一个的id有被赋值,一个没有,最后的结果为:

User{id=1, username='lucy'}
======
User{id=1, username='lucy'}
User{id=2, username='李四'}
User{id=3, username='zhaowu'}

foreach标签:

当我们需要查询出 id为1、2、3时应该怎么做? SQL应该这样写:SELECT * FROM user where id in (1,2,3)。那么使用mybatis的foreach标签应该如何使用?

如何使用?

在UserMapper接口中增加一个方法:List<User> findByIds(int[] arr);

 public List<User> findByIds(int[] arr);

在UserMapper.xml 中编写:

 <select id="findByIds" parameterType="list" resultType="com.dxh.pojo.User">
  SELECT * FROM user
  <where>
   <foreach collection="array" open="id in (" close=")" item="id" separator=",">
    #{id}
   </foreach>
  </where>
 </select>

我们可以看到,foreach中我们使用到了5个值:

  • collection 这里就是写我们传入的类型,如果是数组就是array ,如果是集合就是list
  • open 我们之前说到SELECT * FROM user where id in (1,2,3)正确的SQL应该这样写,那么open就是填写我们需要拼接的前半部分
  • close 填写我们需要拼接的后半部分
  • item 我们需要遍历的值是id,所以就填写id
  • separator ......where id in (1,2,3) 1,2,3之间用,分割。

测试:

 @Test
 public void test2() throws IOException {
  InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
  SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
  SqlSession sqlSession = build.openSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  int[] arr={1,3};
  List<User> byCondition = mapper.findByIds(arr);
  for (User user1 : byCondition) {
   System.out.println(user1);
  }
 }

输出结果:

User{id=1, username='lucy'}
User{id=3, username='zhaowu'}

正确~

最后

这里只是介绍了两个经常使用的标签,mybatis中还有很多标签,比如choose、when、otherwise、trim、set等等

值得一说的是Mybatis的官方网站中已经支持中文了,母语看着更舒服~

https://mybatis.org/mybatis-3/zh/

到此这篇关于Mybatis动态SQL的文章就介绍到这了,更多相关Mybatis动态SQL内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中的i++和++i的区别详解

    java中的i++和++i的区别详解

    这篇文章主要介绍了java中的i++和++i的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Java中SPI的一些理解

    Java中SPI的一些理解

    这篇文章主要介绍了Java中SPI的一些理解,帮助大家更好的理解和学习Java的相关知识,感兴趣的朋友可以了解下
    2020-12-12
  • 教你如何区分Spring与Structs2中间件

    教你如何区分Spring与Structs2中间件

    这篇文章主要介绍了教你如何区分Spring与Structs2中间件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 详解SpringMVC中的日期处理和文件上传操作

    详解SpringMVC中的日期处理和文件上传操作

    这篇文章主要为大家详细介绍了SpringMVC中的日期处理和文件上传操作方法,文中的示例代码讲解详细,对我们学习有一定借鉴价值,需要的可以参考一下
    2022-08-08
  • SpringBoot接口访问频率限制的实现方式

    SpringBoot接口访问频率限制的实现方式

    接口访问频率限制是通过在一定时间内限制用户对接口的访问次数来实现的,在Spring Boot中,我们可以通过多种方式来实现接口的限流,如使用过滤器、拦截器或者借助第三方库,本文给大家讲解的非常详细,需要的朋友可以参考下
    2024-07-07
  • Java 深入浅出分析Synchronized原理与Callable接口

    Java 深入浅出分析Synchronized原理与Callable接口

    Synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行,Runnable是执行工作的独立任务,但是不返回任何值。如果我们希望任务完成之后有返回值,可以实现Callable接口
    2022-03-03
  • Java用Cookie限制点赞次数(简版)

    Java用Cookie限制点赞次数(简版)

    最近做了一个项目,其中有项目需求是,要用cookie实现限制点赞次数,特此整理,把实现代码分享给大家供大家学习
    2016-02-02
  • Netty分布式pipeline管道传播事件的逻辑总结分析

    Netty分布式pipeline管道传播事件的逻辑总结分析

    这篇文章主要为大家介绍了Netty分布式pipeline管道传播事件总结分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • SpringBoot JPA懒加载失效的解决方案(亲测有效)

    SpringBoot JPA懒加载失效的解决方案(亲测有效)

    这篇文章主要介绍了SpringBoot JPA懒加载失效的解决方案(亲测有效),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SpringBoot中注解@AliasFor的使用详解

    SpringBoot中注解@AliasFor的使用详解

    这篇文章主要为大家详细介绍了SpringBoot中注解@AliasFor的用法,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
    2022-05-05

最新评论