2013-01-13 219 views
3

我動態生成MyBatis v3映射器xml中的where子句。但是放置括號非常麻煩。有沒有更簡單的方法來處理不使用if語句的問題?MyBatis - 嵌套條件在哪裏條款

<where> 
    <if test="filter != null"> 
    <choose> 
     <when test="filter.lref != null"> 
     file.lref = #{filter.lref} 
     </when> 
     <otherwise> 
     <!-- I don't want to use this --> 
     <if test="filter.forLike != null || filter.forInt != null"> 
      ( 
     </if> 
     <if test="filter.forLike != null" > 
      subject LIKE #{filter.forLike}  
      OR requester_identifier LIKE #{filter.forLike} 
      OR requester_name LIKE #{filter.forLike} 
     </if> 
     <if test="filter.forInt != null"> 
      OR file_id = #{filter.forInt} 
     </if> 

     <!-- I don't want to use this --> 
     <if test="filter.forLike != null || filter.forInt != null"> 
     ) 
     </if> 
     </otherwise> 
    </choose> 
    </if> 
    <if test="listMode > 0"> 
    <choose> 
     <when test="listMode == 1"> 
     AND file_status_link.dosya_ref is not NULL 
     </when> 
     <otherwise> 
     AND file_status_link.dosya_ref is NULL 
     </otherwise> 
    </choose> 
    </if>    
</where> 

樣品動態生成的SQL輸出如下

WHERE (subject LIKE ? OR requester_identifier LIKE ? OR requester_name LIKE ?) 
AND file_status_link.dosya_ref is NULL 

回答

4

你可以嘗試封裝內<trim>標籤的一部分。這將是這樣的:

<trim prefix="(" prefixOverrides="OR" suffix=")"> 
    <if test="filter.forLike != null" > 
    subject LIKE #{filter.forLike}  
    OR requester_identifier LIKE #{filter.forLike} 
    OR requester_name LIKE #{filter.forLike} 
    </if> 
    <if test="filter.forInt != null"> 
    OR file_id = #{filter.forInt} 
    </if> 
</trim> 
+0

你是對的@partlov。但是它並沒有解決問題:(當'filter.forLike'爲null,那麼'OR'不會被清除,你的建議是處理這種情況所必需的,如果'filter.forLike'和'filter.forInt'都是null如果我們刪除了**不需要的** if子句,那麼SQL輸出是:'WHERE()AND file_status_link.dosya_ref是NULL'無論如何,修剪仍然是解決問題的最接近的選擇 – vahapt

+0

根據你的編輯,如果需要,修剪會自動添加'('和')',另外id'OR'是''內的第一個單詞,它應該替換爲'(' - 那就是由'prefixOverrides'完成 – partlov

+0

現在我完全理解並應用了你的解決方案,謝謝你的澄清,Trim同時執行兩個任務:1.如果底層字符串爲空,則清除前綴 - 後綴。底層字符串從他們開始,謝謝。 – vahapt

0

僞SQL(XML-SQL):

where 
    1 = 1 
    <A>and file.lref = #{filter.lref}</A> 
    <D>and (
     <E> 
     subject like #{filter.forLike}  
     or requester_identifier like #{filter.forLike} 
     or requester_name like #{filter.forLike} 
     </E> 
     <F>or file_id = #{filter.forInt}</F> 
    )</D> 
    </B> 
    <C>and file_status_link.dosya_ref is <G>not</G> null</C> 

其中:

A: <B> && filter.lref != null 
B: filter != null 
D: <B> && (<E> || <F>) 
E: filter.forLike != null 
F: filter.forInt != null 
C: listMode > 0 
G: listMode == 1