Mybatis映射文件(3)

动态SQL

1、if/where

<!--
    test:判断表达式(OGNL自己去查怎么用)
    test="id != null":从参数中取值进行判断
    拼装的时候有的条件没带可能导致sql拼装会有问题
    1、给where后面加上1=1,以后的条件都and
    2、mybatis使用<where>标签来将所有查询条件包括,
    mybatis就会将where标签中拼装的sql多出来的and或者or去掉
    where只会去掉第一个多出来的and或者or
-->
<select id="getEmpsByConditionIfAndWhere" resultType="bean.Employee">
    SELECT * FROM t_employee
    <where>
        <if test="id != null">
             id=#{id}
        </if>
        <if test="lastName != null and lastName != ''">
            AND last_name=#{lastName}
        </if>
        <if test="email != null and email.trim() != ''">
            AND  email=#{email}
        </if>
        <if test="gender==0 or gender==1">
            AND gender=#{gender}
        </if>
    </where>
</select>
2、trim自定义字符串截取规则

<!--
若将and放在每个条件之后,<where>标签不能解决拼接的问题
trim:自定义字符串截取规则
prefix="":前缀:trim标签中是整个字符串拼串后的结果
            prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":前缀覆盖,去掉整个字符串前面多余的字符
suffix="":后缀:
            suffix给拼串后的字符串加一个后缀
suffixOverrides="":后缀覆盖,去掉整个字符串后面多余的
-->
<select id="getEmpsByConditionTrim" resultType="bean.Employee">
    SELECT * FROM t_employee
    <trim prefix="where" suffixOverrides="and">
        <if test="id != null">
            id=#{id} AND
        </if>
        <if test="lastName != null and lastName != ''">
            last_name=#{lastName} AND
        </if>
        <if test="email != null and email.trim() != ''">
            email=#{email} AND
        </if>
        <if test="gender==0 or gender==1">
            gender=#{gender}
        </if>
    </trim>
</select>
3、choose (when, otherwise):分支选择

<!--
如果带了id就用id查,如果带了lastName就用lastName查,只会进入其中一个
-->
<select id="getEmpsByConditionChoose" resultType="bean.Employee">
    SELECT * FROM t_employee
    <where>
        <choose>
            <when test="id!=null">
                id=#{id}
            </when>
            <when test="lastName!=null and lastName!=''">
                last_name LIKE #{lastName}
            </when>
            <when test="email!=null and email!=''">
                email=#{email}
            </when>
            <otherwise>
                1=1
            </otherwise>
        </choose>
    </where>
</select>
4、where-封装查询条件, set-封装修改的条件

<update id="updateEmp">
    UPDATE t_employee
    <set>
        <if test="lastName!=null and lastName!=''">
            last_name=#{lastName},
        </if>
        <if test="email!=null and email!=''">
            email=#{email},
        </if>
        <if test="gender!=null">
            gender=#{gender}
        </if>
    </set>
    <where>
        id=#{id}
    </where>
 <!-- UPDATE t_employee
    <trim prefix="set" suffixOverrides=",">
        <if test="lastName!=null and lastName!=''">
            last_name=#{lastName},
        </if>
        <if test="email!=null and email!=''">
            email=#{email},
        </if>
        <if test="gender!=null">
            gender=#{gender}
        </if>
    </trim>
    <where>
        id=#{id}
    </where>-->
</update>
5、foreach标签——批量处理
<!--
collection:指定要遍历的集合
    list类型的参数会特殊处理封装在map中,map的key就是list
item:将当前遍历出的元素赋值给指定的变量
#{变量名}:就能取出变量的值,也就是当前遍历出的元素

separator:每个元素之间的分隔符
open/close:遍历出所有结果拼接一个开始和结束的字符(整个语句以什么开始和什么结束)
index:索引:遍历list的时候就是索引,item就是当前值
            遍历map的时候就是map的key,item就是map的value
-->
<select id="getEmpsByConditionForeach" resultType="bean.Employee">
    SELECT * FROM t_employee WHERE id IN
        <foreach collection="list" item="item_id" separator="," open="(" close=")">
            #{item_id}
        </foreach>
</select>

<!--批量保存-->
<!--MySQL下批量保存,可以foreach遍历values-->
<!--<insert id="addEmps">
    INSERT INTO t_employee(id,last_name,gender,email) VALUES
    <foreach collection="emps" item="emp" separator=",">
        (#{emp.id},#{emp.lastName},#{emp.gender},#{emp.email})
    </foreach>
</insert>-->
<!--该种方法会有语法异常,需要开启sql语句间用“;”分隔的权限—allowMultiQueries=true-->
<insert id="addEmps">
    <foreach collection="emps" item="emp" separator=";">
        INSERT INTO t_employee(id,last_name,gender,email) VALUES
        (#{emp.id},#{emp.lastName},#{emp.gender},#{emp.email})
    </foreach>
</insert>
6、内置参数和bind
<!--
两个内置参数:
不只是方法传递过来的参数可以被用来判断、取值
mybatis默认还有两个内置参数:
_parameter:代表整个参数
    单个参数:_parameter就是这个参数
    多个参数:参数会被封装为一个map,_parameter就是代表这个map
_databaseId:如果配置了DatabaseIdProvider标签
    _databaseId就是代表当前数据库的别名

bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值
 <bind name="_lastName" value="'%'lastName'%'"></bind>这样写了就可以不用在传入参数的时候写%号
-->
<select id="getEmpsTestInnerParameter" resultType="bean.Employee">
    <bind name="_lastName" value="'%'lastName'%'"></bind>
    <if test="_databaseId=='mysql'">
        SELECT * FROM t_employee
        <if test="_parameter!=null">
            WHERE last_name LIKE #{_lastName}
        </if>
    </if>
    <if test="_databaseId=='oracle'">
        SELECT * FROM employee
        <if test="_parameter!=null">
            WHERE last_name=#{lastName}
        </if>
    </if>
</select>
7、可重用SQL——经常将要查询的列名或插入用的列名抽取出来方便引用
<!--
1、sql标签抽取可重用的sql片段,方便后面引用
    里面还可以做动态判断,经常将查询和插入的列名抽取出来
2、include标签就是引用从外部定义的sql
3、include还可以自定义有些property,sql标签内部就能使用自定义的属性,取值的方式${pro},#{}不可以
-->
<sql id="insertColumn">
    <if test="_databaseId=='mysql'">
      id,last_name,gender,email
    </if>
    <if test="_databaseId=='oracle'">
        --------
    </if>
</sql>
<insert id="addEmps">
    <foreach collection="emps" item="emp" separator=";">
        INSERT INTO t_employee(
        <include refid="insertColumn"></include>
        ) VALUES
        (#{emp.id},#{emp.lastName},#{emp.gender},#{emp.email})
    </foreach>
</insert>

原文地址:https://www.cnblogs.com/huangzhe1515023110/p/9276082.html