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>