MySQL-04 动态SQL

由于本部分内容在SQL映射文件中均按序号注释清楚,故在此仅给出SQL映射文件的具体内容和对应接口类的声明方法。具体请以SQL映射文件为提纲进行查阅。

其中,MyBatis中动态SQL的具体测试代码下载地址:https://download.csdn.net/download/bingbeichen/10530663

SQL映射文件的具体配置如下:

<mapper namespace="com.qiaobc.mybatis.mapper.EmployeeMapper">

    <!-- 1. if判断&OGNL: 实现根据传入参数所携带的字段动态调整查询方式 -->
    <!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
    <select id="getEmpsByConditionIf" resultType="com.qiaobc.mybatis.bean.Employee">
        select id, last_name lastName, gender, email from tbl_employee where 1 = 1
        <!-- test:判断表达式(OGNL) OGNL的具体使用参照官方文档 -->
        <if test="id!=null">
            and id = #{id}
        </if>
        <!-- 特殊字符应写转义字符,如“”需写为''或&quot;&quot; -->
        <if test="lastName!=null and lastName!=''">
            and last_name like #{lastName}
        </if>   
        <!-- OGNL会进行字符串和数字的转换判断 -->
        <if test="gender==0 or gender==1">
            and gender = #{gender}
        </if>
        <if test="email!=null and email.trim()!=&quot;&quot;">
            and email = #{email}
        </if>
    </select>

    <!-- 2. 查询时如果某些条件没带可能导致SQL拼装有问题,比如多出一个and -->
    <!-- 上一部分采用where 1=1 and的方式进行解决,在此借用where标签 -->
    <!-- public List<Employee> getEmpsByConditionWhere(Employee employee); -->
    <select id="getEmpsByConditionWhere" resultType="com.qiaobc.mybatis.bean.Employee">
        select id, last_name lastName, gender, email from tbl_employee
        <!-- where标签可以去掉第一个多出来的and或or,因此应将and或or放在语句之前 -->
        <where>
            <if test="id!=null">
                id = #{id}
            </if>
            <if test="lastName!=null and lastName!=''">
                and last_name like #{lastName}
            </if>
            <if test="gender==0 or gender==1">
                and gender = #{gender}
            </if>
            <if test="email!=null and email.trim()!=&quot;&quot;">
                and email = #{email}
            </if>
        </where>
    </select>

    <!-- 3. Trim标签 -->
    <!-- public List<Employee> getEmpsByConditionTrim(Employee employee); -->
    <select id="getEmpsByConditionTrim" resultType="com.qiaobc.mybatis.bean.Employee">
        select id, last_name lastName, gender, email from tbl_employee
        <!-- where标签无法去掉后边多出的and或or -->
        <!-- 
            prefix="" : 前缀,即给标签体拼装后的字符串加一个前缀
            prefixOverrides="" : 前缀覆盖,即去掉整个字符串前面多余的字符
            suffix="" : 后缀,即给标签体拼装后的字符串加一个后缀
            suffixOverrides="" : 后缀覆盖,即去掉整个字符串后面多余的字符
         -->
        <trim prefix="where" suffixOverrides="and">
            <if test="id!=null">
                id = #{id} and
            </if>
            <if test="lastName!=null and lastName!=''">
                last_name like #{lastName} and
            </if>
            <if test="gender==0 or gender==1">
                gender = #{gender} and
            </if>
            <if test="email!=null and email.trim()!=&quot;&quot;">
                email = #{email}
            </if>
        </trim>
    </select>

    <!-- 4. choose标签:分支选择,只会进入其中一个,如带有id就按id查询,带有name就按name查询 -->

    <!-- 5. set标签:封装修改条件 -->
    <!-- public Boolean updateEmp(Employee employee); -->
    <update id="updateEmp">
        update tbl_employee
        <set>
            <if test="lastName!=null">
                last_name = #{lastName},
            </if>
            <if test="gender!=null">
                gender = #{gender},
            </if>
            <if test="email!=null">
                email = #{email}
            </if>
        </set>
        where id = ${id}
    </update>

    <!-- 6. foreach标签:遍历集合 -->
    <!-- public List<Employee> getEmpsByConditionForeach(List<Integer> ids); -->
    <select id="getEmpsByConditionForeach" resultType="com.qiaobc.mybatis.bean.Employee">
        select id, last_name lastName, gender, email from tbl_employee where id in
        <!-- 
            collection: 指定要遍历的集合;List类型的参数会特殊处理封装在Map中,Map的key就叫List
            item: 将当前遍历的集合元素赋值给指定的变量
            separator: 标签体中各元素间的分隔符
            open: 为标签体遍历完成的字符串拼接一个开始字符
            close: 为标签体遍历完成的字符串拼接一个结束字符
            index: 索引。遍历List时index为索引,item为值;
                        遍历Map时,index为Map对象的key, item为Map对象的value

            #{变量名}:取出变量值,即获取当前遍历出的元素。
         -->
        <foreach collection="ids" item="emp_id" separator="," open="(" close=")">
            #{emp_id}
        </foreach>
    </select>

    <!-- 7. foreach标签 -->
    <!-- public void insertEmps(@Param("emps") List<Employee> emps); -->
    <!-- 7.1 批量保存方式一:MySQL支持values(),(),()语法 -->
    <insert id="insertEmps">
        insert into tbl_employee(last_name, gender, email, dept_id)
        values
        <foreach collection="emps" item="emp" separator=",">
            (#{emp.lastName}, #{emp.gender}, #{emp.email}, #{emp.dept.id})
        </foreach>
    </insert>
    <!-- 7.2 批量保存方式二:需要MySQL数据库连接属性allowMultiQueries=true -->
    <!-- 直接设置:jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true -->
    <insert id="insertEmps">
        <foreach collection="emps" item="emp" separator=";">
            insert into tbl_employee(last_name, gender, email, dept_id)
            values(#{emp.lastName}, #{emp.gender}, #{emp.email}, #{emp.dept.id})
        </foreach>
    </insert>

    <!-- Oracle数据库批量保存:Oracle不支持values(),(),()方式,只支持如下两种方式:
        1).多个insert放在begin - end里面
            begin
                insert into employees(employee_id,last_name,email) 
                values(employees_seq.nextval,'test_001','[email protected]');
                insert into employees(employee_id,last_name,email) 
                values(employees_seq.nextval,'test_002','[email protected]');
            end;
        2).利用中间表:
            insert into employees(employee_id,last_name,email)
               select employees_seq.nextval,lastName,email from(
                      select 'test_a_01' lastName,'test_a_e01' email from dual
                      union
                      select 'test_a_02' lastName,'test_a_e02' email from dual
                      union
                      select 'test_a_03' lastName,'test_a_e03' email from dual
               )    
     -->

     <!-- 8. 内置参数_parameter与_databaseId -->
     <!-- 
        _parameter:代表整个参数
            单个参数:_parameter就是这个参数
            多个参数:参数会被封装为一个map;_parameter就是代表这个map

        _databaseId:若配置了databaseIdProvider标签,则_databaseId即代表当前数据库的别名
      -->
     <!--public List<Employee> getEmpsTestInnerParameter(Employee employee);  -->
     <select id="getEmpsTestInnerParameter" resultType="com.qiaobc.mybatis.bean.Employee">
            <!-- 9. bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值 -->
            <bind name="_lastName" value="'%'+lastName+'%'"/>
            <if test="_databaseId=='mysql'">
                select * from tbl_employee
                <if test="_parameter!=null">
                    where last_name like #{_lastName}
                </if>
            </if>
            <if test="_databaseId=='oracle'">
                select * from employees
                <if test="_parameter!=null">
                    where last_name like #{_parameter.lastName}
                </if>
            </if>
      </select>

      <!-- 10. 抽取可重用的SQL片段,以方便多处引用 
        1).sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
        2).使用include标签来引用已经抽取的SQL片段
        3).include标签还可自定义property,sql标签内部即能使用自定义的属性
                include-property:取值的正确方式${prop},而不能使用#{}的方式
      -->
      <sql id="insertColumn">
            <if test="_databaseId=='oracle'">
                employee_id,last_name,email
            </if>
            <if test="_databaseId=='mysql'">
                last_name,email,gender,d_id
            </if>
      </sql>

</mapper>

对应接口类的声明方法如下:

public interface EmployeeMapper {

    public List<Employee> getEmpsByConditionIf(Employee employee);

    public List<Employee> getEmpsByConditionWhere(Employee employee);

    public List<Employee> getEmpsByConditionTrim(Employee employee);

    public Boolean updateEmp(Employee employee);

    public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids);

    public void insertEmps(@Param("emps") List<Employee> emps);

}

猜你喜欢

转载自blog.csdn.net/bingbeichen/article/details/80972832