mybatis--動態SQL,sql裏使的各種標籤

一、if判斷

  <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.dao.EmployeeMapperDynamicSQL">
    <!-- 
• if:判斷
• choose (when, otherwise):分支選擇;帶了break的swtich-case
    如果帶了id就用id查,如果帶了lastName就用lastName查;只會進入其中一個
• trim 字符串截取(where(封裝查詢條件), set(封裝修改條件))
• foreach 遍歷集合
     -->
     <!-- 查詢員工,要求,攜帶了哪個字段查詢條件就帶上這個字段的值 -->
     <!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
     <select id="getEmpsByConditionIf" resultType="com.mybatis.bean.Employee">
        select * from tbl_employee
        <!-- where
          mybats使用<where>標籤時來將所有的查詢條件包括在內,mybatis就會將where標籤裏多餘的and或or去掉,
便會出現問題
        -->
        <where>
            <!-- test:判斷表達式(OGNL)
            OGNL參照PPT或者官方文檔。
                 c:if  test
            從參數中取值進行判斷

            遇見特殊符號應該去寫轉義字符:
            &&:&amp;&amp;
            '':&quot;
            還可以調用相應方法:email.trim(),去除前後空格
            -->
            <if test="id!=null">
                id=#{id}
            </if>
            <if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
                and last_name like #{lastName}
            </if>
            <if test="email!=null and email.trim()!=&quot;&quot;">
                and email=#{email}
            </if> 
            <!-- ognl會進行字符串與數字的轉換判斷  "0"==0 -->
            <if test="gender==0 or gender==1">
                and gender=#{gender}
            </if>
        </where>
     </select>

二、 trim 自定義字符串的截取規則

<!--public List<Employee> getEmpsByConditionTrim(Employee employee);  -->
     <select id="getEmpsByConditionTrim" resultType="com.mybatis.bean.Employee">
        select * from tbl_employee
        <!-- 後面多出的and或者or where標籤不能解決 
        prefix="":前綴:trim標籤體中是整個字符串拼串 後的結果。
                prefix給拼串後的整個字符串加一個前綴 
        prefixOverrides="":
                前綴覆蓋: 去掉整個字符串前面多餘的字符
        suffix="":後綴
                suffix給拼串後的整個字符串加一個後綴 
        suffixOverrides=""
                後綴覆蓋:去掉整個字符串後面多餘的字符

        -->
        <!-- 自定義字符串的截取規則 -->
        <trim prefix="where" suffixOverrides="and">
            <if test="id!=null">
                id=#{id} and
            </if>
            <if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
                last_name like #{lastName} and
            </if>
            <if test="email!=null and email.trim()!=&quot;&quot;">
                email=#{email} and
            </if> 
            <!-- ognl會進行字符串與數字的轉換判斷  "0"==0 -->
            <if test="gender==0 or gender==1">
                gender=#{gender}
            </if>
         </trim>
     </select>

此標籤使的情況並不是很多

三、 choose分支選擇

做一個選擇查詢,如果參數帶了id便用id進行查詢,如果帶了lastName便用lastName進行查詢,即只進入一個分支。如下例:

<!-- public List<Employee> getEmpsByConditionChoose(Employee employee); -->
    <select id="getEmpsByConditionChoose" resulType="com.mybatis.bean.Employee">
        select * from tbl_employee
        <where>
            <choose>
                <when test="id != null">
                    id=#{id}
                </when>
                <when test="lastName!=null">
                    last_name like #{lastName}
                </when>
                <when test="email!=null">
                    email = #{email}
                </when>
                <otherwise>
                    gender = 0
                </otherwise>
            </choose>
        </where>
    </select>

四、 set 封裝修改條件

set標籤同where標籤有一樣的功能, set標籤可以去掉多餘的逗號,如果不用標籤,只有set那可以會應該某些條件沒有傳值,而有多餘的逗號,從而導致報錯。當然也可以使用上述的trim自定義字符串,如下例:

 <update id="updEmp">
    update tbl_employee 
     <set>
         <if test="lastName!=null">
            last_name=#{lastName},
        </if>
        <if test="email!=null">
            email=#{email},
        </if>
        <if test="gender!=null">
            gender=#{gender}
        </if>
    </set>       
 </update>
             <!---Trim:更新拼串-->
        update tbl_employee 
        <trim prefix="set" suffixOverrides=",">
            <if test="lastName!=null">
                last_name=#{lastName},
            </if>
            <if test="email!=null">
                email=#{email},
            </if>
            <if test="gender!=null">
                gender=#{gender}
            </if>
        </trim>
        where id=#{id}  
     </update>

五 、foreach

<!--public List<Employee> getEmpsByConditionForeach(List<Integer> ids);  -->
     <select id="getEmpsByConditionForeach" resultType="com.mybatis.bean.Employee">
        select * from tbl_employee
        <!--
            collection:指定要遍歷的集合:
                list類型的參數會特殊處理封裝在map中,map的key就叫list
            item:將當前遍歷出的元素賦值給指定的變量
            separator:每個元素之間的分隔符
            open:遍歷出所有結果拼接一個開始的字符
            close:遍歷出所有結果拼接一個結束的字符
            index:索引。遍歷list的時候是index就是索引,item就是當前值
                          遍歷map的時候index表示的就是map的key,item就是map的值

            #{變量名}就能取出變量的值也就是當前遍歷出的元素
          -->
        <foreach collection="ids" item="item_id" separator=","
            open="where id in(" close=")">
            #{item_id}
        </foreach>
     </select>

使用foreach可以完成批量插入,其批量插入有兩種方法如下:
1

 <!-- 批量保存 -->
     <!--public void addEmps(@Param("emps")List<Employee> emps);  -->
     <!--MySQL下批量保存:可以foreach遍歷   mysql支持values(),(),()語法-->
    <insert id="addEmps">
        insert into tbl_employee(last_name,email, gender,d_id) 
        values
        <foreach collection="emps" item="emp" separator=",">
            (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
        </foreach>
     </insert>

2.

<!-- 這種方式需要數據庫連接屬性allowMultiQueries=true;
        這種分號分隔多個sql可以用於其他的批量操作(刪除,修改) -->
     <insert id="addEmps">
        <foreach collection="emps" item="emp" separator=";">
            insert into tbl_employee(last_name,email,gender,d_id)
            values(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
        </foreach>
     </insert> 

注:數據庫配置如 allowMultiQueries可如下:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true
jdbc.username=root
jdbc.password=123456

但是oracle數據庫的批量保存跟mysql有所不同:

 <!-- Oracle數據庫批量保存: 
        Oracle不支持values(),(),()
        Oracle支持的批量方式
        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
               )    
     -->
      <insert id="addEmps" databaseId="oracle">
        <!-- oracle第一種批量方式 -->
        <foreach collection="emps" item="emp" open="begin" close="end;">
            insert into employees(employee_id,last_name,email) 
                values(employees_seq.nextval,#{emp.lastName},#{emp.email});
        </foreach>
<!-- oracle第二種批量方式  -->
    <insert id="addEmps" databaseId="oracle" >
        insert into employees(employee_id,last_name,email)
        select employees_seq.nextval,lastName,email from(
            <foreach collection="emps" item="emp" separator="union">
                select #{emp.lastName} lastName,#{emp.emial} email from dual
            </foreach>
        )
     </insert>
<!--也可以使用foreach裏的open和close屬性改變上述寫法-->
    <insert id="addEmps" databaseId="oracle" >
        insert into employees(employee_id,last_name,email)
            <foreach collection="emps" item="emp" separator="union"
             open="select employees_seq.nextval,lastName,email from(" 
             close=")">
                select #{emp.lastName} lastName,#{emp.emial} email from dual
            </foreach>
        )
     </insert>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章