先看一段代碼:
<select id="select" resultMap="HotelinfoResult" parameterClass="java.util.Map"> select id, HotelId as hotelId, Selectflag as selectflag from Hotelinfokuxun <dynamic prepend=" WHERE "> <isPropertyAvailable property="idList"> <isNotNull property="idList" prepend=" and id in "> <iterate property="idList" conjunction="," close=")" open="("> #idList[]# </iterate> </isNotNull> </isPropertyAvailable> </dynamic> </select>
預計預計產生的SQL是:
select id, HotelId as hotelId,Selectflag as selectflag from Hotelinfok WHERE id in (?,?,?,?)
需要注意的是:iBatis對於第一個prepend=" and " 是要移除的,如果不移除,則SQL 陳述式就是:
select id, HotelId as hotelId,Selectflag as selectflag from Hotelinfok WHERE and id in (?,?,?,?) //顯然這樣的SQL是錯誤的,iBatis移除了字句中第一個and
顯然and是不能存在的,iBatis對於動態SQL移除第一個and,但是本例中in字句還包含” and id in",也同時被移除了,所以程式產生報錯:
org.springframework.jdbc.BadSqlGrammarException: SqlMapClient operation; bad SQL grammar []; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException: --- The error occurred while applying a parameter map. --- Check the Hotelinfokuxun.select-InlineParameterMap. --- Check the statement (query failed). --- Cause: java.sql.SQLException: Operand should contain 1 column(s)
當前面的<isPropertyAvilable>都沒有匹配上, prepend="and id in "子句作為第一個prepend時,就會被移除,程式就報錯
實際產生的SQL語句是:
select id, HotelId as hotelId,Selectflag as selectflag from Hotelinfok WHERE (?,?,?,?) //少了應該存在的" id in "
解決方案:
一:增加一個無效的1='1'
<isPropertyAvailable property="idList"><isNotNull prepend=" and ">1='1'</isNotNull><isNotNull property="idList" prepend=" and id in "><iterate property="idList" conjunction="," close=")" open="(">#idList[]#</iterate></isNotNull></isPropertyAvailable>
產生的SQL語句:
select id, HotelId as hotelId,Selectflag as selectflag from Hotelinfok WHERE 1='1'and id in (?,?,?,?)
二:放棄使用In子句
<isPropertyAvailable property="idList"><isNotNull property="idList" prepend=" and "><iterate property="idList" conjunction="OR" close=")" open="(">id=#idList[]#</iterate></isNotNull> </isPropertyAvailable>
產生的SQL語句是:
select id, HotelId as hotelId,Selectflag as selectflag from Hotelinfok WHERE ( id=? OR id=? OR id=? OR id=?)