Mybatis中XML的文件SQL语句与动态sql标签(trim|where|set|foreach|if|choose|when|otherwise|bind)

在xml中写sql语句有很多的规范、标准,有时候想要找对应的例子还得翻一翻以前的代码,这里干脆对遇到的情况做个记录。

一,新建XML文件


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.web">
    
mapper>
  1. mapper:映射文件的根节点,只有一个属性namespace(命名空间),作用如下 : 用于区分不同的mapper,全局唯一。绑定DAO接口,即面向接口编程,当绑定一个接口,就不用写此接口的实现类,会通过接口的完全限定名找到对应的mapper配置来执行语句,所以,namespace的命名必须要写接口的完全限定名。
  2. cache:配置给定命名空间的缓存。
  3. cache-ref:从其他命名空间引用缓存配置。
  4. resultMap:用来描述数据库结果集和对象的对应关系。
  5. sql:可以重用的块,也可以被其他语句引用。通常时存放一些公用性的。
  6. insert:映射插入语句。update:更新映射语句。delete:删除映射语句。select:映射查询语句。
  7. XML中特殊符号需要转义
< < 小于
> > 大于
& & 和号
' 省略号
" " 引号

二,SQL语句

  1. SELECT(if标签,foreach标签)

    <select id="select_b01byb00" parameterType="string" resultType="java.util.LinkedHashMap">
    	SELECT * FROM A WHERE A00 = #{A00}
        <if test="A01 != null and A01 != ''">
            AND
            <foreach collection="A01" item="item" open="(" close=")" separator="or">
                regexp_replace(A.A01,'\s+','') LIKE '%'||regexp_replace(#{item},'\s+','')||'%' 
            foreach>
        if>
    select>
    
    1. id: sql语句的身份证号,parameterType: 参数类型,可以写实体类的路径,resultType: 返回类型。
    2. if test = "": xml中用来判断是否走下面语句的操作。
    3. foreach: 用来拼接循环参数
      • collection: 用来循环的数组或集合
      • item: 集合中的单个元素
      • open: foreach语句开始前拼接的sql
      • close: foreach语句结束后拼接的sql
      • separator: foreach中的语句用什么来连接起来
    4. '\s+': 空格
    5. ||: 合并符
  2. UPDATE(set标签)

    <update id="UpdateTableA"  parameterType="string">
        UPDATE A
       <set>
     		<if test="A01!=null ">
            	A01 = #{A01},
       		if>
    		<if test="A02!=null">
    			UPDATETIME = SYSDATE,
    		if>
    		<if test="A03!=null">
    			A03 = #{A03,jdbcType=TIMESTAMP},
    		if>
    	set>
        WHERE RECORDID = #{RECORDID}
    update>
    
    1. SYSDATE: 系统时间
    2. TO_DATE(): 把前台组件传过来的时间转成数据库能识别的Date类型
    3. set: 如果set标签中有值,则会在前面拼接一个set,若没值则不会拼接,自动去掉最后多余的逗号
  3. INSERT(trim标签)

    <insert id="insertAZ09" parameterType="map">
      INSERT INTO AZ09
      <trim prefix="(" suffix=")" suffixOverrides=",">
      	RECORDID,
      	<if test="A00 != null and A00 != ''">A00,if>
      	<if test="dmDate != null and dmDate != ''">ZX247,if>
      	<if test="grade != null and grade != ''">ZR050,if>
      	<if test="reason != null and reason != ''">ZX249,if>
      trim>
      <trim prefix=" values (" suffix=")" suffixOverrides=",">
      	GET_UUID,
      	<if test="A00 != null and A00 !=''">#{A00},if>
      	<if test="dmDate != null and dmDate != ''">to_date(#{dmDate}, 'yyyy.mm.dd'),if>
      	<if test="grade != null and grade != ''">#{grade},if>
      	<if test="reason != null and reason != ''">#{reason},if>
      trim>
    insert>
    
    1. trim: 用来去掉sql语句中多余的拼接符号
    2. prefix: 前缀
    3. suffix: 后缀
    4. suffixOverrides=",": 后缀会覆盖掉最后一个,
    5. prefixOverrides : 前缀会覆盖第一个指定的值
  4. DELETE

    <delete id="deleteTableA" parameterType="map">
        DELETE FROM A WHERE A00=#{A00,jdbcType=VARCHAR}
    delete>
    

三、九种动态sql标签

Mybatis动态sql是做什么的?都有哪些动态sql?能简述⼀下动态sql的执⾏原理不?

  • Mybatis动态sql可以让我们在Xml映射⽂件内,以标签的形式编写动态sql,完成逻辑判断和动态
    拼接sql的功能。
  • Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind
  • 其执⾏原理为,使⽤OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此
    来完成动态sql的功能。

3.1. TRIM

  mybatis的trim标签一般用于去除sql语句中多余的and关键字,逗号,或者给sql语句前拼接 “where“、“set“以及“values(“ 等前缀,或者添加“)“等后缀,可用于选择性插入、更新、删除或者条件查询等操作。

属性 作用
prefix 在sql语句前拼接的内容
suffix 在sql语句后拼接的内容
prefixOverrides 可以去掉在sql语句中前面指定的内容,比如去掉多余的拼接符AND、OR
suffixOverrides 可以去掉在sql语句中后面指定的内容,比如去掉多余的拼接符,

<select id="getEmpByMap" parameterType="map" resultMap="empMap">
    SELECT * FROM EMPLOYEE
    <trim prefix="WHERE" prefixOverrides="AND">
        <if test="EMP01 != null">
            AND EMP01 = #{EMP01}
        if>
        <if test="EMP02 != null">
            AND EMP02 = #{EMP02}
        if>
        <if test="EMP03 != null">
            AND EMP03 = TO_DATE(#{EMP03}, 'YYYY.MM.DD')
        if>
    trim>
select>

当map 为{EMP01=周康, EMP02=1, EMP03=1968.10.07}时,sql语句是这样的:

--prefix为sql语句前拼接了WHERE, prefixOverrides去掉了第一个EMP01前面的多余的AND连接符
SELECT * WHERE EMP01 = ? AND EMP02 = ? AND EMP03 = TO_DATE(?, 'yyyy-mm-dd hh24:mi:ss')

3.2. WHERE

  where 主要是用来简化 sql 语句中 where 条件判断,自动地处理 AND/OR 条件。

    
    <select id="getEmpByMap" parameterType="map" resultMap="empMap">
        SELECT * FROM EMPLOYEE
        <where>
            <if test="EMP01 != null">
                AND EMP01 = #{EMP01} /*姓名*/
            if>
            <if test="EMP02 != null">
                AND EMP02 = #{EMP02} /*性别*/
            if>
            <if test="EMP03 != null">
                AND EMP03 = TO_DATE(#{EMP03}, 'yyyy-mm-dd hh24:mi:ss') /*出生日期*/
            if>
        where>
    select>

当map 为{EMP01=周康, EMP02=1, EMP03=1968.10.07}时,sql语句是这样的:

//where标签会在里面有内容时自动为sql语句添加一个where, 同时去掉where后面紧接的and/or, 如果没有则跳过
SELECT * FROM EMPLOYEE WHERE EMP01 = ? AND EMP02 = ? AND EMP03 = TO_DATE(?, 'yyyy-mm-dd hh24:mi:ss')

当map 为{}时,sql语句是这样的:

//当where标签中无值时, mybatis不会为sql语句添加where标签
SELECT * FROM EMPLOYEE

3.3. SET

  用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。


<update id="updateEmpByEmp00" parameterType="map">
    UPDATE EMPLOYEE
    <set>
        <if test="EMP02 != null">EMP02 = #{EMP02},if>
        <if test="EMP04 != null">EMP04 = #{EMP04},if>
        <if test="EMP05 != null">EMP05 = #{EMP05},if>
    set>
    WHERE EMP00 = #{EMP00}
update>

当map 为{EMP00=7350F9DE-F5BC-461A-B499-F86680D2DA4E, EMP02=2, EMP04=429005}时,sql语句是这样的:

//set标签会在里面有值时自动添加set, 且会去掉语句中最后 EMP04 后面多余的逗号
UPDATE EMPLOYEE SET EMP02 = ?, EMP04 = ? WHERE EMP00 = ?
//注: 若set标签中无值, sql语句会报错, ORA-00971: 缺失 SET 关键字

3.4. FOREACH

  foreach标签主要用于构建in条件,他可以在sql中对集合进行迭代。

属性 作用
collection 指你传进来的数组或者容器类型,array 或 collection
item 迭代器中每个元素的别名,随意取
separator 多个参数之间用什么拼接(,or and…)
open 在迭代器开始前拼接的sql,迭代器中的sql 会自动拼接在它后面
close 在迭代器结束后拼接的sql,指定的内容会在迭代器中的sql 拼接完之后自动拼接在最后
index 相当于for 循环中的 i

<select id="getEmpByMap" parameterType="map" resultMap="empMap">
    SELECT * FROM EMPLOYEE WHERE
    <foreach collection="EMP01" item="emp" separator="," open="EMP01 IN (" close=")">
        #{emp}
    foreach>
select>

当map 为{EMP01=[周康, 杨国兴, 万正阳, 刘晓鹏]}时,sql语句是这样的:

//foreach会将传进来的集合或者数组进行迭代处理, 然后拼接sql语句, foreach还可以使用split方法, 像Java那样截取字符串
SELECT * FROM EMPLOYEE WHERE EMP01 IN ( ? , ? , ? , ? )
//Parameters: 周康(String), 杨国兴(String), 万正阳(String), 刘晓鹏(String)

3.5. IF

  if 标签多用于情况判断,判断某一字段是否为空。

<!--查询员工-->
<select id="getEmpByMap" parameterType="map" resultMap="empMap">
    SELECT * FROM EMPLOYEE
    <trim prefix="WHERE" prefixOverrides="AND">
        <if test="EMP01 != null AND EMP01 != ''">
            AND EMP01 = #{EMP01}
        </if>
        <if test="EMP02 != null AND EMP02 != ''">
            AND EMP02 = #{EMP02}
        </if>
        <if test="EMP03 != null AND EMP03 != ''">
            AND EMP03 = TO_DATE(#{EMP03}, 'YYYY.MM.DD')
        </if>
    </trim>
</select>

当map 为{EMP01=周康, EMP02=1}时,sql语句是这样的:

//if test 中的表达式为true 时才会在sql 中拼接if 标签中的内容
SELECT * WHERE EMP01 = ? AND EMP02 = ?

3.6. CHOOSE

  choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。


<select id="getEmpByMap" parameterType="map" resultMap="empMap">
    SELECT * FROM EMPLOYEE
    <where>
        <choose>
            <when test="EMP01 != null">
                EMP01 = #{EMP01}
            when>
            <when test="EMP02 != null">
                EMP02 = #{EMP02}
            when>
            <otherwise>
                EMP01 = '测试'
            otherwise>
        choose>
    where>
select>

当map 为{EMP01=周康, EMP02=2}时,sql语句是这样的:

//choose只会选择一个when
SELECT * FROM EMPLOYEE WHERE EMP01 = ?
//Parameters: 周康(String)

当map 为{}时,sql语句是这样的:

//当choose中没有满足的条件时, 会选择otherwise 中的条件
SELECT * FROM EMPLOYEE WHERE EMP01 = '测试'

3.7. WHEN

  when 标签多用于choose 标签中,就像Java 中的swich 的case。

3.8. OTHERWISE

  otherwise 标签多用于choose 标签中,就像Java 中的swich 的default。

3.9. BIND

  bind 标签可以使用 OGNL 表达式创建一个变量井将其绑定到上下文中,这样做可以提前处理一些参数。

属性 作用
name 新创建的的变量在上下文的名字
value 新创建变量的值,可以接收传进来的参数值

 <select id="getEmpByName" parameterType="string" resultMap="empMap">
     SELECT * FROM EMPLOYEE
     <where>
         <if test="EMP01 != null">
             <bind name="bindEMP01" value=" '%' + EMP01 + '%' "/>
             EMP01 LIKE #{bindEMP01}
         if>
     where>
 select>

当map 为{EMP01=张}时,sql语句是这样的:

//bind可以提前处理传入的参赛并创建一个新的变量绑定到上下文中
SELECT * FROM EMPLOYEE WHERE EMP01 LIKE ?
//Parameters: %张%(String)

你可能感兴趣的:(第三方组件,算法,java,开发语言,xml,mybatis)