MyBatis 的强大特性之一便是它的动态 SQL。可以根据不同条件拼接 SQL 语句。

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。主要由以下几种元素。

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

1、if  (判断)

实例:根据条件查询酒店列表

hotelMapper接口

  1. package com.pjf.mybatis.dao;
  2.  
  3. import java.util.List;
    import com.pjf.mybatis.po.Hotel;
  4.  
  5. public interface HotelMapper {
  6.  
  7. public List<Hotel> getHotel(Hotel hotel);
  8.  
  9. }

hotelMapper.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12.  
  13. <!-- resultMap使用 -->
  14. <select id="getHotel" resultMap="myHotel">
  15. select*
  16. from hotel
  17. where
  18. <if test="id!=null">
  19. id=#{id}
  20. </if>
  21. <if test="hotelName!=null &amp;&amp; hotelName!=&quot;&quot;">
  22. and hotel_name like concat('%',#{hotelName},'%')
  23. </if>
  24. <if test="price!=null">
  25. and price> #{price}
  26. </if>
  27. </select>
  28. </mapper>

测试类

  1. package com.pjf.mybatis;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.util.List;import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.Test;
  10.  
  11. import com.pjf.mybatis.dao.HotelMapper;import com.pjf.mybatis.po.Hotel;
  12.  
  13. public class TestHotel {
  14.  
  15. public SqlSessionFactory sqlSessionFactory() throws IOException {
  16. // mybatis的配置文件
  17. String resource = "mybatis_config.xml";
  18. // 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
  19. InputStream is = Resources.getResourceAsStream(resource);
  20. // 构建sqlSession的工厂
  21. SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
  22. return sessionFactory;
  23. }
  24.  
  25. @Test
  26. public void getHotel() throws IOException {
  27.  
  28. SqlSessionFactory sessionFactory = sqlSessionFactory();
  29. SqlSession session = sessionFactory.openSession();
  30. HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
  31. System.out.println(hotelMapper.getClass());
  32. Hotel hotel = new Hotel(1001, "南京", "", 800);
  33. List<Hotel> list = hotelMapper.getHotel(hotel);
  34. for (Hotel hotel1 : list) {
  35. System.out.println(hotel1);
  36. }
  37. session.close();
  38. }
  39. }

查看结果

需要注意的是特殊字符需要转义,

  1. <if test="hotelName!=null &amp;&amp; hotelName!=&quot;&quot;">

常用的有以下字符

2、where

对于上面的查询条件,如果在测试类中

  1. Hotel hotel = new Hotel(1001, "南京", "", 800);改成 Hotel hotel = new Hotel(null,"南京","", 800);
    结果会怎么样

sql多了一个and

解决:

a、增加默认条件1=1

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12.  
  13. <!-- resultMap使用 -->
  14. <select id="getHotel" resultMap="myHotel">
  15. select*
  16. from hotel
  17. where 1=1
  18. <if test="id!=null">
  19. id=#{id}
  20. </if>
  21. <if test="hotelName!=null &amp;&amp; hotelName!=&quot;&quot;">
  22. and hotel_name like concat('%',#{hotelName},'%')
  23. </if>
  24. <if test="price!=null">
  25. and price> #{price}
  26. </if>
  27. </select>
  28. </mapper>

结果

b、增加where元素

将所有的元素放在where标签内,where元素会自动去除首位的and或or。注意是首位的and或者or。

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12.  
  13. <!-- resultMap使用 -->
  14. <select id="getHotel" resultMap="myHotel">
  15. select*
  16. from hotel
  17. <where>
  18. <if test="id!=null">
  19. id=#{id}
  20. </if>
  21. <if test="hotelName!=null &amp;&amp; hotelName!=&quot;&quot;">
  22. and hotel_name like concat('%',#{hotelName},'%')
  23. </if>
  24. <if test="price!=null">
  25. and price> #{price}
  26. </if>
  27. </where>
  28. </select>
  29. </mapper>

3、trim  (字符串截取)

如果and写在语句的末尾,该怎么解决呢

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12.  
  13. <!-- resultMap使用 -->
  14. <select id="getHotel" resultMap="myHotel">
  15. select*
  16. from hotel
  17. <where>
  18. <if test="id!=null">
  19. id=#{id} and
  20. </if>
  21. <if test="hotelName!=null &amp;&amp; hotelName!=&quot;&quot;">
  22. hotel_name like concat('%',#{hotelName},'%') and
  23. </if>
  24. <if test="price!=null">
  25. price> #{price}
  26. </if>
  27. </where>
  28. </select>
  29. </mapper>

测试类

  1. package com.pjf.mybatis;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. import org.apache.ibatis.io.Resources;
  9. import org.apache.ibatis.session.SqlSession;
  10. import org.apache.ibatis.session.SqlSessionFactory;
  11. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  12. import org.junit.Test;
  13.  
  14. import com.pjf.mybatis.dao.HotelMapper;
  15. import com.pjf.mybatis.po.City;
  16. import com.pjf.mybatis.po.Hotel;
  17.  
  18. public class TestHotel {
  19.  
  20. public SqlSessionFactory sqlSessionFactory() throws IOException {
  21. // mybatis的配置文件
  22. String resource = "mybatis_config.xml";
  23. // 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
  24. InputStream is = Resources.getResourceAsStream(resource);
  25. // 构建sqlSession的工厂
  26. SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
  27. return sessionFactory;
  28. }
  29.  
  30. @Test
  31. public void getHotel() throws IOException {
  32.  
  33. SqlSessionFactory sessionFactory = sqlSessionFactory();
  34. SqlSession session = sessionFactory.openSession();
  35. HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
  36. Hotel hotel = new Hotel(1001,"南京","",null);
  37. System.out.println(hotel);
  38. List<Hotel> list = hotelMapper.getHotel(hotel);
  39. for (Hotel hotel1 : list) {
  40. System.out.println(hotel1);
  41. }
  42. session.close();
  43. }
  44. }

结果:末尾就会多一个and

这时候就可以通过trim标签来解决:

trim 对trim标签体中拼接后的字符串进行操作

  1. prefix 对拼接后的字符串加前缀
  2. prefixOverrides 对拼接后的字符串去前缀
  3. suffix 对拼接后的字符串加后缀
  4. suffixOverrides 对拼接后的字符串去后缀
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12.  
  13. <select id="getHotel" resultMap="myHotel">
  14. select*
  15. from hotel
  16. <!-- trim 对trim标签体中拼接后的字符串进行操作
  17. prefix 对拼接后的字符串加前缀
  18. prefixOverrides 对拼接后的字符串去前缀
  19. suffix 对拼接后的字符串加后缀
  20. suffixOverrides 对拼接后的字符串去后缀
  21. -->
  22. <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and">
  23. <if test="id!=null">
  24. id=#{id} and
  25. </if>
  26. <if test="hotelName!=null &amp;&amp; hotelName!=&quot;&quot;">
  27. hotel_name like concat('%',#{hotelName},'%') and
  28. </if>
  29. <if test="price!=null">
  30. price> #{price}
  31. </if>
  32. </trim>
  33. </select>
  34. </mapper>

这样就解决了

4、choose (分支选择)

MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。,但不同的是mybatis进入了一个分支后就不再进入其他分支。

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12. <select id="getHotel" resultMap="myHotel">
  13. select*
  14. from hotel
  15. <where>
  16. <choose>
  17. <when test="id!=null">
  18. id=#{id}
  19. </when>
  20. <when test="hotelName!=null &amp;&amp; hotelName!=&quot;&quot;">
  21. hotel_name like concat('%',#{hotelName},'%')
  22. </when>
  23. <when test="hotelAddress!=null &amp;&amp; hotelAddress!=&quot;&quot;">
  24. hotel_address=#{hotelAddress}
  25. </when>
  26. <when test="price!=null">
  27. price>#{price}
  28. </when>
  29. <otherwise>
  30. 1=1
  31. </otherwise>
  32. </choose>
  33. </where>
  34. </select>
  35. </mapper>

5、set

前面我们使用update可以进行全字段更新,但是如果是带了什么字段就更新什么字段,该怎么做呢。

可是使用set和if的结合,此外,set标签能自动删除末尾多余的逗号。

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12.  
  13. <update id="updateHotel">
  14. update hotel
  15. <set>
  16. <if test="hotelName!=null">
  17. hotel_name=#{hotelName},
  18. </if>
  19. <if test="price!=null">
  20. price=#{price}
  21. </if>
  22. </set>
  23. <where>
  24. id=#{id}
  25. </where>
  26. </update>
  27. </mapper>

6、foreach

用来对集合进行遍历

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
  4.  
  5. <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
  6. <id column="id" property="id" jdbcType="INTEGER" />
  7. <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
  8. <result column="hotel_address" property="hotelAddress"
  9. jdbcType="VARCHAR" />
  10. <result column="price" property="price" jdbcType="INTEGER" />
  11. </resultMap>
  12.  
  13. <!-- resultMap使用 -->
  14. <select id="getHotel" resultMap="myHotel">
  15. select*
  16. from hotel where id in
  17. <!-- collection 指要遍历的集合 1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  18. 2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  19. 3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
  20. item 将遍历出的元素赋值给指定的变量
  21. separator 每个元素之间的分隔符
  22. open 遍历出的结果拼接出一个开始符
  23. close 遍历出的结果拼接一个结束符
  24. index 索引
  25. -->
  26. <foreach collection="list" item="ids" separator="," open="(" close=")">
  27. #{ids}
  28. </foreach>
  29. </select>
  30. </mapper>

测试类

  1. package com.pjf.mybatis;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import java.util.Map;
  8.  
  9. import org.apache.ibatis.io.Resources;
  10. import org.apache.ibatis.session.SqlSession;
  11. import org.apache.ibatis.session.SqlSessionFactory;
  12. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  13. import org.junit.Test;
  14.  
  15. import com.pjf.mybatis.dao.HotelMapper;
  16. import com.pjf.mybatis.po.City;
  17. import com.pjf.mybatis.po.Hotel;
  18.  
  19. public class TestHotel {
  20.  
  21. public SqlSessionFactory sqlSessionFactory() throws IOException {
  22. // mybatis的配置文件
  23. String resource = "mybatis_config.xml";
  24. // 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
  25. InputStream is = Resources.getResourceAsStream(resource);
  26. // 构建sqlSession的工厂
  27. SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
  28. return sessionFactory;
  29. }
  30.  
  31. @Test
  32. public void getHotel() throws IOException {
  33.  
  34. SqlSessionFactory sessionFactory = sqlSessionFactory();
  35. SqlSession session = sessionFactory.openSession(true);
  36. HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
  37. List<Integer> id =new ArrayList<Integer>();
  38. id.add(1001);
  39. id.add(1002);
  40. id.add(1003);
  41. List<Hotel> list= hotelMapper.getHotel(id);
  42. for (Hotel hotel : list) {
  43. System.out.println(hotel);
  44. }
  45. session.close();
  46. }
  47. }

7、bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。

  1. <select id="getHotel" resultMap="myHotel">
  2. <bind name="_hotelName" value="'%' + hotelName + '%'" />
  3. SELECT * FROM hotel
  4. WHERE hotel_name LIKE #{_hotelName}
  5. </select>

mybatis学习(九)——动态sql的更多相关文章

  1. mybatis学习 十 动态 SQL

    1.  根据方法传入的参数不同执行不同的 SQL 命令.称为动态 SQL, MyBatis 中动态 SQL 就是在 mapper.xml 中添加逻辑判断等. 2. <if>标签 <s ...

  2. mybatis学习之动态sql

    mybatis的动态sql语句很强大,在mapper映射文件中使用简单的标签即可实现该效果,下面一个个记录: 1.select查询 简单的select类似如下: <select id=" ...

  3. mybatis 学习五 动态SQL语句

    3.1 selectKey 标签 在insert语句中,在Oracle经常使用序列.在MySQL中使用函数来自动生成插入表的主键,而且需要方法能返回这个生成主键.使用myBatis的selectKey ...

  4. Mybatis学习笔记-动态SQL

    概念 根据不同环境生成不同SQL语句,摆脱SQL语句拼接的烦恼[doge] 本质:SQL语句的拼接 环境搭建 搭建数据库 CREATE TABLE `blog`( `id` VARCHAR(50) N ...

  5. 【mybatis深度历险系列】mybatis中的动态sql

    最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...

  6. Mybatis入门之动态sql

    Mybatis入门之动态sql 通过mybatis提供的各种标签方法实现动态拼接sql. 1.if.where.sql.include标签(条件.sql片段) <sql id="sel ...

  7. mybatis 详解------动态SQL

    mybatis 详解------动态SQL   目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...

  8. mybatis中的动态SQL

    在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...

  9. Mybatis映射文件动态SQL语句-01

    因为在很多业务逻辑复杂的项目中,往往不是简单的sql语句就能查询出来自己想要的数据,所有mybatis引入了动态sql语句, UserMapper.xml <?xml version=" ...

  10. Java数据持久层框架 MyBatis之API学习九(SQL语句构建器详解)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

随机推荐

  1. xcdatamodel的实质

    修改后缀名为zip或者其它,可以查看到xcdatamodel是一个描述文件 <?xml version="1.0" encoding="UTF-8" st ...

  2. MySQL基础教程——创建数据库并插入数据

    本节将介绍 MySQL 新建数据库,新建表,插入数据以及基本数据类型的相关知识.本节实验将创建一个名为 mysql_shiyan 的数据库,其中有两张表 employee和 department. 1 ...

  3. mac层到ath9k层,ath9k层到硬件层

    如上图,整个 mac 层分成两个部分——UMAC 和 LMAC.LMAC 分成 MAC 下半部分和硬件抽象层. 硬件抽象层和ath9k层的连接 在hw.h中的函数struct ath_hw_ops() ...

  4. bootstrap 翻页的状态

    翻页的状态 下面的实例演示了上表中所讨论的 class .disabled 的用法: <!DOCTYPE html><html><head><meta htt ...

  5. GTA5(侠盗猎车5)中文版破解版

    )中文版破解版迅雷下载地址(使用迅雷新建任务填上地址): magnet:?xt=urn:btih:65F16B126D8A656E4FC825DE204EBFAF04B070FC

  6. 深入理解ES6箭头函数的this以及各类this面试题总结

    ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性,俘获了大批粉丝儿 它也可能是面试中的宠儿, 我们关键要搞清楚 箭头函数和普通函数中的this 一针见血式总结: 普通函数中的 ...

  7. tensorflow目标检测API安装及测试

    1.环境安装配置 1.1 安装tensorflow 安装tensorflow不再仔细说明,但是版本一定要是1.9 1.2 下载Tensorflow object detection API  下载地址 ...

  8. 【单调队列】P1886 滑动窗口

    GET 单调队列 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: Th ...

  9. UVa 12171 题解

    英文题面不怎么友好,大家还是自行通过紫书了解题面吧... 解题思路: 1. 面对500 ^ 3的数据范围,我们需要先用离散化解决掉爆空间的问题. 2. 由于我们要求的总体积包括内空部分的体积,我们可以 ...

  10. TSS (任务状态段)的作用及结构

    1.什么是TSS TSS全称Task State Segment ,是操作系统在进行进程切换时保存进程现场信息的段 2.TSS什么时候用,有什么用 TSS在任务(进程)切换时起着重要的作用,通过它保存 ...