在xml中写sql语句有很多的规范、标准,有时候想要找对应的例子还得翻一翻以前的代码,这里干脆对遇到的情况做个记录。
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.web">
mapper>
< |
< | 小于 |
---|---|---|
> |
> | 大于 |
& |
& | 和号 |
' |
’ | 省略号 |
" |
" | 引号 |
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>
id
: sql语句的身份证号,parameterType
: 参数类型,可以写实体类的路径,resultType
: 返回类型。if test = ""
: xml中用来判断是否走下面语句的操作。foreach
: 用来拼接循环参数
collection
: 用来循环的数组或集合item
: 集合中的单个元素open
: foreach语句开始前拼接的sqlclose
: foreach语句结束后拼接的sqlseparator
: foreach中的语句用什么来连接起来'\s+'
: 空格||
: 合并符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>
SYSDATE
: 系统时间TO_DATE()
: 把前台组件传过来的时间转成数据库能识别的Date类型set
: 如果set标签中有值,则会在前面拼接一个set,若没值则不会拼接,自动去掉最后多余的逗号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>
trim
: 用来去掉sql语句中多余的拼接符号prefix
: 前缀suffix
: 后缀suffixOverrides=","
: 后缀会覆盖掉最后一个,
prefixOverrides
: 前缀会覆盖第一个指定的值DELETE
<delete id="deleteTableA" parameterType="map">
DELETE FROM A WHERE A00=#{A00,jdbcType=VARCHAR}
delete>
Mybatis动态sql是做什么的?都有哪些动态sql?能简述⼀下动态sql的执⾏原理不?
trim
|where
|set
|foreach
|if
|choose
|when
|otherwise
|bind
。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')
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
用于动态更新语句的类似解决方案叫做 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 关键字
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)
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 = ?
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 = '测试'
when 标签多用于choose 标签中,就像Java 中的swich 的case。
otherwise 标签多用于choose 标签中,就像Java 中的swich 的default。
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)