Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL 是动态变
化的,此时在前面的学习中我们的 SQL 就不能满足要求了。
参考的官方文档,描述如下:

Dynamic SQL

One of the most powerful features of MyBatis has always been its Dynamic SQL capabilities. If you have any experience with JDBC or any similar framework, you understand how painful it is to conditionally concatenate strings of SQL together, making sure not to forget spaces or to omit a comma at the end of a list of columns. Dynamic SQL can be downright painful to deal with.

While working with Dynamic SQL will never be a party, MyBatis certainly improves the situation with a powerful Dynamic SQL language that can be used within any mapped SQL statement.

The Dynamic SQL elements should be familiar to anyone who has used JSTL or any similar XML based text processors. In previous versions of MyBatis, there were a lot of elements to know and understand. MyBatis 3 greatly improves upon this, and now there are less than half of those elements to work with. MyBatis employs powerful OGNL based expressions to eliminate most of the other elements:

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

动态 SQL

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

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

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

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

一、动态 SQL <if>标签

我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。比如在 id 如果不为空时可以根据 id 查询,
如果 username 不为空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
/**
* 根据用户信息,查询用户列表
* @param user
* @return
*/
List<User> findByUser(User user);
<select id="findByUser" resultType="user" parameterType="user">select * from user where 1=1<if test="username!=null and username != '' ">and username like #{username}</if><if test="address != null">and address like #{address}</if></select>
注意:<if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用~! 另外注意这里使用了别名,要在SqlMapConfig.xml中配置别名
@Testpublic void testFindByUser() {User u = new User();u.setUserName("%王%");u.setAddress("%顺义%");//6.执行操作List<User> users = userDao.findByUser(u);for(User user : users) {System.out.println(user);} }

二、动态 SQL <where>标签

为了简化上面 where 1=1 的条件拼装,我们可以采用<where>标签来简化开发。

<!-- 根据用户信息查询 --><select id="findByUser" resultType="user" parameterType="user">select * from user<where><if test="username!=null and username != '' ">and username like #{username}</if><if test="address != null">and address like #{address}</if></where></select>

三、动态标签之<foreach>标签

1.需求

传入多个 id 查询用户信息,用下边两个 sql 实现:
SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)
这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。
这样我们将如何进行参数的传递?

2. QueryVo 中加入一个 List 集合用于封装参数

/*** <p>Title: QueryVo</p>* <p>Description: 查询条件对象</p>*/
@Data
public class QueryVo implements Serializable {private User user;private List<Integer> ids;
}

3.其他代码和配置

/**
* 根据 id 集合查询用户
* @param vo
* @return
*/
List<User> findInIds(QueryVo vo);
<!-- 查询所有用户在 id 的集合之中 --><select id="findInIds" resultType="user" parameterType="queryVo"><!-- select * from user where id in (1,2,3,4,5); -->select * from user<where><if test="ids != null and ids.size() > 0"><foreach collection="ids" open="id in ( " close=")" item="uid"separator=",">#{uid}</foreach></if></where></select>
SQL 语句:
select 字段 from user where id in (?)
<foreach>标签用于遍历集合,它的属性:
     collection:代表要遍历的集合元素,注意编写时不要写#{}
     open:代表语句的开始部分
     close:代表结束部分
     item:代表遍历集合的每个元素,生成的变量名
     sperator:代表分隔符
@Testpublic void testFindInIds() {QueryVo vo = new QueryVo();List<Integer> ids = new ArrayList<Integer>();ids.add(41);ids.add(42);ids.add(43);ids.add(46);ids.add(57);vo.setIds(ids);List<User> users = userDao.findInIds(vo);for (User user : users) {System.out.println(user);}}

四、Mybatis 中简化编写的 SQL 片段

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。

1.定义SQL片段

<!-- 抽取重复的语句代码片段 -->
<sql id="defaultSql">select * from user
</sql>

2.引用代码片段

<!-- 配置查询所有操作 --><select id="findAll" resultType="user"><include refid="defaultSql"></include></select>

8-Mybatis 的动态 SQL 语句相关推荐

  1. java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】...

    第1章 Mybatis 连接池与事务深入 1.1 Mybatis 的连接池技术 1.1.1 Mybatis 连接池的分类 1.1.2 Mybatis 中数据源的配置 1.1.3 Mybatis 中 D ...

  2. MyBatis中动态sql语句标签详解

    动态 SQL 通常写在mapper包下面的地址映射配置文件(.xml)中.根据条件的不同, SQL 语句也会随之动态的改变. MyBatis 中,提供了一组标签用于实现动态 SQL. 动态SQL语句标 ...

  3. Mybatis的动态sql语句的查询

    if <select id="findActiveBlogWithTitleLike"resultType="Blog">SELECT * FROM ...

  4. mybatis实现动态sql语句

    [注意点] choose与if区别,只取第一个符合条件password并没有进入sql语句中 //[请注意]增删改必须提交事务................. 在批量更新中需要将deconfig的配 ...

  5. Mybatis中动态Sql语句的拼接分析

    一.动态查询 1.方式一: <!--if标签--><!--if中的test属性必须录入,其内部为ognl表达式,不需要#{}.如果test内满足,则主体语句执行--><s ...

  6. Mybatis 动态Sql语句《常用》

    MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格,还要注意省掉 ...

  7. 【转】mybatis实战教程(mybatis in action)之八:mybatis 动态sql语句

    转自:除非申明,文章均为一号门原创,转载请注明本文地址,谢谢! 转载地址:http://blog.csdn.net/kutejava/article/details/9164353#t5 1. if ...

  8. Mybatis—动态SQL语句与逆向工程

    Mybatis动态SQL语句与逆向工程 MyBatis动态SQL语句与逆向工程 1.动态SQL语句 1.1.动态SQL是什么 1.2.动态SQL有什么用 1.3.基于XML的实现 1.3.2.接口文件 ...

  9. Java神鬼莫测之MyBatis注解开发之动态SQL语句(六)

    1.Mybatis注解开发之动态SQL语句 背景:使用mybatis的注解开发动态Sql会比较麻烦, 很不方便, 所以不太推荐使用,该文章以查询作为案例,演示动态sql语句. 注意:Mybatis的动 ...

  10. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

最新文章

  1. 电源适配器和充电器的区别和关系
  2. Windows 驱动发展基金会(九)内核函数
  3. python时间模块哪个好arrow模块_python库: arrow (时间)
  4. 检查虚ip跟实ip之间网络问题_虚电路有哪些特点 虚电路原理介绍【详解】
  5. XML文件处理的思考
  6. STL(一)——栈及其应用
  7. SSAS知识回放之订单数据分析
  8. The Closest M Points//kd树+优先队列
  9. 中标麒麟Linux安装微信,中标麒麟微信群,剧透中标麒麟7.0
  10. TwinCAT 3 xml存储配置文件程序
  11. SSR pac模式配置和Gitee转移图床失败的尝试
  12. 基于python的简易安卓小外挂制作
  13. python实现匿名发邮件_python 发送匿名邮件或无发件人
  14. c++实验三:继承与派生
  15. 企业业务架构设计方法论及实践(二)
  16. Windows下的systeminfo命令获取系统信息
  17. 成功解决raise AssertionError(“Torch not compiled with CUDA enabled“)AssertionError: Torch not compiled
  18. 20221211英语学习
  19. kaldi windows安装_kaldi 在 Windows 下的使用
  20. linux服务器解压zip文件

热门文章

  1. python基于svm的异常检测_[scikit learn]:异常检测-OneClassSVM的替代方案
  2. 【Kafka】Flink 消费 kafka 部分 分区 一直不提交 offset
  3. 【ElasticSearch】Es 源码之 CcrRestoreSourceService 源码解读
  4. 【nginx】nginx 简介 基本概念 介绍
  5. Flink 1.9报错:No implicits found for parameter evidence$2: TypeInformation[(String, String, String)]
  6. maven:同一个项目内模块之间互相调用
  7. Tachyou alluxio初识
  8. Java如何判断整数溢出,溢出后怎么得到提示?
  9. WPF TextBox控件中文字实现垂直居中
  10. linux把mysql变为服务器_linux mysql服务器迁移