原文:http://blog.csdn.net/shan9liang/article/details/40452375
先簡單說下Mybatis的動態sql,這不是今天的重點。
MyBatis的動態SQL是基於OGNL表達式的,它可以幫助我們方便的在SQL語句中實現某些邏輯。
例如,sql語句where條件中,需要一些安全判斷,例如按某一條件查詢時如果傳入的參數是空,此時查詢出的結果很可能是空的,也許我們需要參數為空時,是查出全部的信息
MyBatis中用於實現動態SQL的元素主要有:
- if
- choose(when,otherwise)
- trim
- where
- set
- foreach
<select id="findActiveBlogLike" parameterType="BLOG" resultType="BLOG"> SELECT * FROM BLOG WHERE <trim prefix="WHERE" prefixOverrides="AND |OR "> <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND title like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </trim> </select> <update id="updateAuthorIfNecessary" parameterType="Author"> update Author <trim prefix="where" prefixOverrides=","> <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email}</if> </set> where id=#{id} </trim> </update>
翻閱mybatis文檔,在一個不起眼的地方發現update標簽有一個屬性statementType,根據jdbc的經驗,這應該是控制sql預編譯還是非預編譯的,如果sql執行是預編譯的,那么動態傳入字段名,表名之類的,顯然
是不行的,所以你必須改成非預編譯的。
兩者有什么區別呢?如果是預編譯的,那么系統在初始化時就會讀取這段sql代碼,將指定的實體類中的字段替換了類似#{}這樣的語句,就是形成了類似這樣的語句:
"select * from tableName where id=?" 這個時候你在系統運行時再想向這句sql中替換tableName或者id,結果可想而知。如果是非預編譯呢,結果剛好相反,他會在系統運行時才會去生成這樣類似的語句。此時就可以去替換這些動態的字段或者表名之類。這樣在結合之前所講的返回類型的設置,我們的問題就解決了。
我們可以不用設定參數和返回類型的實體類,只需要形成一個動態的表名和字段名的列表類。就可以動態對那些未知的物理模型進行操作.如下代碼可作參考:
<select id="queryMetaList" resultType="Map" statementType="STATEMENT"> select * from ${tableName} t where <foreach item="item" index="index" collection="field" open=" " separator="and" close=" "> <choose> <when test="item.fieldType == 'DATE' and item.dateQueryFlag == 0"> ${item.fieldCode} between to_date('${item.fieldValue}','yyyy-mm-dd hh24:mi:ss') </when> <when test="item.fieldType == 'DATE' and item.dateQueryFlag == 1"> to_date('${item.fieldValue}','yyyy-mm-dd hh24:mi:ss') </when> <when test="item.fieldItemCode != null and item.fieldItemCode != ''"> ${item.fieldCode} = '${item.fieldItemCode}' </when> <otherwise> ${item.fieldCode} = '${item.fieldValue}' </otherwise> </choose> </foreach> </select>