1. 程式人生 > >MyBatis動態SQL大全

MyBatis動態SQL大全

一、什麼是動態SQL

MyBatis的動態SQL是基於OGNL的表示式的。它對SQL語句進行靈活的操作,通過表示式判斷來實現對SQL的靈活拼接、組裝。

二、動態SQL介紹

下面是用於實現動態SQL的主要元素:

if
choose(when,otherwise)
trim
where
set
foreach

(1)、if元素
在動態SQL中所作的最通用的事情就是包含部分where子句的條件

<select id="getList" parameterType="java.util.Map" resultType="com.boya.app.loan.blo.model.BLoLoanInfo">
		SELECT
			<include refid="column"/>
		FROM B_LO_LOAN_INFO t
		<trim prefix="WHERE" prefixOverrides="AND |OR ">
			<if test="id != null and id != ''">
				AND t.ID = #{id}
			</if>
		</trim>
	</select>

2.choose,when,otherwise元素。類似java中的switch…case…,MyBatis提提供choose

<select id="getLoanInfoList" parameterType="java.util.Map" resultType="com.by.loan.manage.dto.BLoLoanInfoDto">
    <choose>
      <!-- 有機構查詢條件,查詢它及它以下 -->
      <when test="orgIds != null and orgIds != ''">
        SELECT aa.*,aa.staffNo instUserNo FROM
        (
        SELECT
        <include refid="column"/>
        FROM B_LO_LOAN_INFO t
        LEFT JOIN b_lo_loan_prod c on c.LOAN_NO = t.LOAN_NO
        LEFT JOIN b_lo_cust_info b on b.CUST_NO = t.CUST_NO
        LEFT JOIN b_lo_loan_fund_match m ON t.LOAN_NO = m.LOAN_NO
        LEFT JOIN b_lo_loan_branch h on h.LOAN_NO = t.LOAN_NO
        LEFT JOIN b_lo_loan_saler s ON s.LOAN_NO = t.LOAN_NO
        <trim prefix="WHERE" prefixOverrides="AND |OR ">
          <if test="loanNo != null and loanNo != ''">
            AND t.LOAN_NO like CONCAT('%',#{loanNo},'%')
          </if>
        </trim>
        ) aa
        JOIN
        (
        select distinct c.LOGIN_NAME from
        (SELECT id FROM A_SYS_ORG WHERE FIND_IN_SET(ID,#{orgIds})>0) a
        join a_sys_user_org b on a.id=b.ORG_ID
        join a_sys_user c on c.ID=b.USER_ID
        ) bb
        ON bb.LOGIN_NAME=aa.staffNo
        ORDER BY aa.applyDate DESC, aa.regDate DESC
      </when>
      <!-- 沒有機構查詢條件 -->
      <otherwise>
        SELECT
        s.STAFF_NO instUserNo,
        n.channel_Code channelCode,
        <include refid="column"/>
        FROM B_LO_LOAN_INFO t
        LEFT JOIN b_lo_loan_prod c on c.LOAN_NO = t.LOAN_NO
        LEFT JOIN b_lo_cust_info b on b.CUST_NO = t.CUST_NO
        LEFT JOIN b_lo_loan_fund_match m ON t.LOAN_NO = m.LOAN_NO
        LEFT JOIN b_lo_loan_branch h on h.LOAN_NO = t.LOAN_NO
        LEFT JOIN b_lo_loan_saler s ON s.LOAN_NO = t.LOAN_NO
        LEFT join b_cu_cust_channel_info n on n.PHONE_NO = b.PHONE_NO 
			
        <trim prefix="WHERE" prefixOverrides="AND |OR ">
	      <if test='channelCode == "nChannel"'>
			   AND ( n.channel_Code = '' or n.CHANNEL_CODE  IS NULL )
		  </if>
        </trim>
        ORDER BY t.APPLY_DATE DESC, t.REG_DATE DESC
      </otherwise>
    </choose>
  </select>

3.trim元素
trim和where同級,其主要功能是可以在自己包含的內容前或後加上某些前後綴,與之對應的屬性是prefix和suffix;也可以把內容的首部或尾部的某些內容覆蓋,對應的屬性是prefixOverrides和suffixOverrides;

<update id="updateByPrimaryKey" parameterType="java.util.Map">
		<trim prefix="SET" suffixOverrides=",">
			<if test="loanNo != null">
				LOAN_NO = #{loanNo},
			</if>
			<if test="custNo != null">
				CUST_NO = #{custNo},
			</if>
		</trim>
		WHERE LOAN_NO=#{loanNo}
	</update>

4.set元素

set元素可以被用於動態包含更新的列,不包含不需要更新的,並且會動態的前置set關鍵字,也可以相除任意無關的逗號。

<update id="updateUser" parameterType="com.mybatis.VO.UserVO">    
    update user_table   
    <set>   
        <if test="userId !=null and userId !=''">    
            AND A.userId = #{userId,jdbcType=CHAR}    
        </if>    
        <if test="userName !=null and userName !=''">    
            AND A.userName = #{userName,jdbcType=CHAR}    
        </if>   
    </set>          
    where userId=#{id}    
</update>  

5.foreach元素
foreach的主要用在構建in條件中,他可以迭代一個集合。foreach元素的屬性主要有:item,index,collection,open,separator,close。

下面對屬性進行簡單的介紹:

item:表示集合中每一個元素進行迭代時的別名。

index:指定一個名字,用於表示在迭代過程中每次迭代的位置。

open:表示以什麼開始。

separator:每次迭代以什麼分割。

close:以什麼關閉。

collection:最重要且必須指定的有三種情況:

1.如果傳入的是單獨引數的List型別時,collection的屬性值為list。

2.如果傳入的是單獨引數的陣列時,collection的屬性值為array.

3.如果傳入多個引數時,我們把多個引數放入map中,單引數也可以放入map中。map中的key就是引數名,所以collection屬性值就是傳入的List或者array物件在Map裡的key。

下面列舉每種情況的案例:

1.單引數List型別:

<select id="batchSelect" resultType="UserVO" parameterType="java.util.Map>  
        select userId,userName,userAge,userPhone from user_table where userId in  
        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">  
            #{item}  
        </foreach>  
    </select>  

2.單引數陣列array型別

<select id="batchSelect" resultType="UserVO" parameterType="java.util.Map>  
    select userId,userName,userAge,userPhone from user_table where userId in  
    <foreach collection="array" index="index" item="item" open="(" separator="," close=")">  
        #{item}  
    </foreach>  
</select>  

3.多引數Map型別

<select id="batchSelect" resultType="UserVO" parameterType="java.util.Map">  
     select userId,userName,userAge,userPhone from user_table where userId in  
     <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">  
         #{item}  
     </foreach>  
 </select>  

對應的分裝成map的部分java程式碼:

List<Integer> ids = new ArrayList<Integer>();  
        ids.add(1);  
        ids.add(2);  
        ids.add(3);  
        ids.add(6);  
        ids.add(7);  
        ids.add(9);  
        Map<String, Object> params = new HashMap<String, Object>();  
        params.put("ids", ids);  

批量插入方法:

<insert id="insertBatch">
    INSERT INTO t_user
            (id, name, del_flag)
    VALUES
    <foreach collection ="list" item="user" separator =",">
         (#{user.id}, #{user.name}, #{user.delFlag})
    </foreach >
</insert>

作者:談笑_風生
來源:CSDN
原文:https://blog.csdn.net/m0_37981235/article/details/79131493
版權宣告:本文為博主原創文章,轉載請附上博文連結!

5、Case when then else end用法:
直接上一次例子:

<select id="getAllStatList" parameterType="java.lang.String" resultType="java.util.HashMap">
		SELECT
			s.REPAY_DATE repayDate,
			s.RCV_TOTAL_AMT rcvTotalAmt,
			s.ACT_TOTAL_AMT actTotalAmt,
			s.REPAY_NUM repayNum,
			s.OVDU_FLAG ovduFlag,
		  (CASE WHEN s.ACT_TOTAL_AMT>=s.RCV_TOTAL_AMT THEN '13900001' ELSE '13900002' END) isHaveRepayed
		FROM
			c_acc_loan_acct_stat s
		WHERE
			LOAN_NO = #{loanNo};
	</select>