Mybatis之动态SQL

mybatis 的动态sql语句是基于OGNL表达式的。可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:

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

if

动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。

  1. <select id="selectUserByOrgid" resultType="java.util.HashMap">
  2. select username,password from sys_user where org_id = #{orgid,jdbcType=VARCHAR}
  3. <if test="orderFiled != null" >
  4. order by ${orderFiled}
  5. <if test="orderSort != null" >
  6. ${orderSort}
  7. </if>
  8. </if>
  9. </select>

choose, when, otherwise

有些时候,我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

  1. <select id="selectByUsernameORorg" parameterType="java.lang.String" resultMap="BaseResultExtMap">
  2. select
  3. <include refid="Base_Ext_Column_List" />
  4. from sys_user
  5. where
  6. <choose>
  7. <when test="username != null">
  8. AND username like#{username,jdbcType=VARCHAR}
  9. </when>
  10. <when test="name != null ">
  11. AND name like #{name,jdbcType=VARCHAR}
  12. </when>
  13. <otherwise>
  14. AND org_id =#{orgid,jdbcType=VARCHAR}
  15. </otherwise>
  16. </choose>
  17. </select>

trim, where, set

前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题。为了解决前面SQL可能出现的问题,就是使用where标签改写。where标签非常智能。如果标签内部没有合适的语句,where标签就不会生成任何东西,防止出现错误语句。

  1. <select id="selectByUsernameORorg2" parameterType="java.lang.String" resultMap="BaseResultExtMap">
  2. select
  3. <include refid="Base_Ext_Column_List" />
  4. from sys_user
  5. <where>
  6. <if test="name != null">
  7. name = #{name,jdbcType=VARCHAR}
  8. </if>
  9. <if test="username != null">
  10. AND username like #{username,jdbcType=VARCHAR}
  11. </if>
  12. </where>
  13. </select>

有时候where标签还不能满足需求。这时候还可以使用trim标签进行更高级的定制。trim标签中的prefix和suffix属性会被用于生成实际的SQL语句,会和标签内部的语句拼接。如果语句的前面或后面遇到prefixOverrides或suffixOverrides属性中指定的值,MyBatis会自动将它们删除。在指定多个值的时候,别忘了每个值后面都要有一个空格,保证不会和后面的SQL连接在一起。下面这个例子和where标签完全等效。

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

类似的用于动态更新语句的解决方案叫做 set。set 元素可以被用于动态包含需要更新的列,而舍去其他的。

  1. <update id="updateByPrimaryKeySelective" parameterType="com.goku.mybatis.model.sysUser">
  2. <!--
  3. WARNING - @mbg.generated
  4. This element is automatically generated by MyBatis Generator, do not modify.
  5. -->
  6. update sys_user
  7. <set>
  8. <if test="username != null">
  9. username = #{username,jdbcType=VARCHAR},
  10. </if>
  11. <if test="password != null">
  12. password = #{password,jdbcType=VARCHAR},
  13. </if>
  14. <if test="name != null">
  15. name = #{name,jdbcType=VARCHAR},
  16. </if>
  17. <if test="sex != null">
  18. sex = #{sex,jdbcType=VARCHAR},
  19. </if>
  20. <if test="status != null">
  21. status = #{status,jdbcType=CHAR},
  22. </if>
  23. <if test="orgId != null">
  24. org_id = #{orgId,jdbcType=VARCHAR},
  25. </if>
  26. <if test="email != null">
  27. email = #{email,jdbcType=VARCHAR},
  28. </if>
  29. <if test="idcard != null">
  30. idcard = #{idcard,jdbcType=VARCHAR},
  31. </if>
  32. <if test="isAdmin != null">
  33. is_admin = #{isAdmin,jdbcType=VARCHAR},
  34. </if>
  35. <if test="sort != null">
  36. sort = #{sort,jdbcType=BIGINT},
  37. </if>
  38. <if test="mobile != null">
  39. mobile = #{mobile,jdbcType=VARCHAR},
  40. </if>
  41. <if test="stationid != null">
  42. stationid = #{stationid,jdbcType=LONGVARCHAR},
  43. </if>
  44. </set>
  45. where id = #{id,jdbcType=VARCHAR}
  46. </update>

这里,set 元素会动态前置 SET 关键字,同时也会消除无关的逗号,因为用了条件语句之后很可能就会在生成的赋值语句的后面留下这些逗号。

若你对等价的自定义 trim 元素的样子感兴趣,那这就应该是它的真面目:

  1. <trim prefix="SET" suffixOverrides=",">
  2. ...
  3. </trim>

foreach

动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候

  1. <select id="selectUserByOrgid2" resultType="java.util.HashMap">
  2. select username,password from sys_user where org_id IN
  3. <foreach item="item" index="index" collection="list"
  4. open="(" separator="," close=")">
  5. #{item}
  6. </foreach>
  7. </select>

bind

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

  1. <select id="selectByUsername2" parameterType="java.lang.String" resultMap="BaseResultExtMap">
  2. <bind name="username" value="'%' + username + '%'" />
  3. select
  4. <include refid="Base_Ext_Column_List" />
  5. from sys_user
  6. where username LIKE #{username}
  7. </select>

GITHUB

github :  https://github.com/nbfujx/learn-java-demo/tree/master/Goku.MybatisDemo.XML

Mybatis基于XML配置SQL映射器(三)的更多相关文章

  1. Mybatis基于XML配置SQL映射器(二)

    Mybatis之XML注解 之前已经讲到通过 mybatis-generator 生成mapper映射接口和相关的映射配置文件: 下面我们将详细的讲解具体内容 首先我们新建映射接口文档  sysUse ...

  2. Mybatis基于XML配置SQL映射器(一)

    Durid和Mybatis开发环境搭建 SpringBoot搭建基于Spring+SpringMvc+Mybatis的REST服务(http://www.cnblogs.com/nbfujx/p/76 ...

  3. mybatis 基于xml 配置的映射器

    cache  给命名空间的缓存配置 cache-ref 其他命名空间缓存配置的引用 resultMap 描述如何从数据库结果集中来加载对象 <!--column不做限制,可以为任意表的字段,而p ...

  4. Java Persistence with MyBatis 3(中文版) 第三章 使用XML配置SQL映射器

    关系型数据库和SQL是经受时间考验和验证的数据存储机制.和其他的ORM 框架如Hibernate不同,MyBatis鼓励开发者可以直接使用数据库,而不是将其对开发者隐藏,因为这样可以充分发挥数据库服务 ...

  5. MyBatis学习笔记3--使用XML配置SQL映射器

    <resultMap type="Student" id="StudentResult"> <id property="id&quo ...

  6. 小峰mybatis(5)mybatis使用注解配置sql映射器--动态sql

    一.使用注解配置映射器 动态sql: 用的并不是很多,了解下: Student.java 实体bean: package com.cy.model; public class Student{ pri ...

  7. (三)使用XML配置SQL映射器

    SqlSessionFactoryUtil.java package com.javaxk.util; import java.io.IOException; import java.io.Input ...

  8. 小峰mybatis(4)mybatis使用注解配置sql映射器

    主流开发还是使用xml来配置:使用注解配置比较快,但是不支持所有功能:有些功能还是得用配置文件: 一.基本映射语句: @Inert @Update @Delete @Select 二.结果集映射语句 ...

  9. MyBatis 3 使用注解配置SQL映射器

    l 在映射器Mapper接口上使用注解 l 映射语句 @Insert,@Update,@Delete,@SeelctStatements l 结果映射 一对一映射 一对多映射 l 动态SQL @Sel ...

随机推荐

  1. jmeter.bat无法启动

    jmeter.bat启动时提示:'findstr' 不是内部或外部命令,也不是可运行的程序或批处理文件. 学习中遇到的问题: 'findstr' 不是内部或外部命令,也不是可运行的程序或批处理文件. ...

  2. 查看mysql数据库文件存放位置

    show variables like '%basedir%' 也是可以的,这是查找mysql的安装路径

  3. 4412 RS485

    一.485硬件原理 差分对传输数据的原理 IO数据的传输→差分对 rs232传输的距离在15米以下,RS485传输距离是几十米到1000米以上 为什么485可以传输这么远 差分对的机制可以降低电磁场的 ...

  4. [CSP-S模拟测试]:养花(分块)

    题目描述 小$C$在家种了$n$盆花,每盆花有一个艳丽度$a_i$.在接下来的$m$天中,每天早晨他会从一段编号连续的花中选择一盆摆放在客厅,并在晚上放回.同时每天有特定的光照强度$k_i$,如果这一 ...

  5. 两个图层一上一下div view

    <view class="main"> <view class="user-info"> </view> <view ...

  6. Apache: No space left on device: Couldn’t create rewrite_map(XXXX)

    启动apache的时候 有时候会遇到这样的错误:No space left on device: Couldn’t create rewrite_map(XXXX) 第一眼看以为是磁盘没有空间了,其实 ...

  7. Configuring IPMI under Linux using ipmitool

    http://www.thomas-krenn.com/en/wiki/Configuring_IPMI_under_Linux_using_ipmitool Configuring IPMI und ...

  8. 【VisualStdio】在VS2015中显示上下文菜单中“创建单元测试”菜单

    ---恢复内容开始--- VS2012以后创建单元测试的选项被默认隐藏了,创建单元测试变得无比低效率.看msdn的说法好像是想推荐使用Intell Test来替代单元测试的用途,但是还没摸清楚也不敢瞎 ...

  9. Oracle下定时删除归档日志脚本

    一.报错信息 前几天网站突然访问不了,并且报了如下错误: ora-27101: shared memory realm does not exist ora-01034: oracle not ava ...

  10. Python中的装饰器,迭代器,生成器

    1. 装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1和2的 ...