1. 程式人生 > >MyBatis傳入參數與parameterType

MyBatis傳入參數與parameterType

http lean ota clob mod 導致 字符 轉義字符 一個

1. 傳入簡單類型


Java代碼:

Java代碼 技術分享圖片
  1. public User get(Long id) {
  2. return (User) getSqlSession().selectOne("com.liulanghan.get" , id);
  3. }


MAPPER :

Xml代碼 技術分享圖片
  1. <select id="findUserListByIdList" parameterType="java.lang.Long" resultType="User">
  2. select * from user where id = #{id};
  3. </select>


2. 傳入List

JAVA代碼:

Java代碼 技術分享圖片
  1. public List<Area> findUserListByIdList(List<Long> idList) {
  2. return getSqlSession().selectList("com.liulanghan.findUserListByIdList", idList);
  3. }

MAPPER :

Xml代碼 技術分享圖片
  1. <select id="findUserListByIdList" parameterType="java.util.ArrayList" resultType="User">
  2. select * from user user
  3. <where>
  4. user.ID in (
  5. <foreach item="guard" index="index" collection="list"
  6. separator=","> #{guard} </foreach>
  7. )
  8. </where>
  9. </select>



單獨傳入list時,foreach中的collection必須是list,不不管變量的具體名稱是什麽。比如這裏變量名為idList,
collection卻是是list。

3. 傳入數組


JAVA代碼:

Java代碼 技術分享圖片
  1. public List<Area> findUserListByIdList(int[] ids) {
  2. return getSqlSession().selectList("com.liulanghan.findUserListByIdList", ids);
  3. }

MAPPER :

Xml代碼 技術分享圖片
  1. <select id="findUserListByIdList" parameterType="java.util.HashList" resultType="User">
  2. select * from user user
  3. <where>
  4. user.ID in (
  5. <foreach item="guard" index="index" collection="array"
  6. separator=","> #{guard} </foreach>
  7. )
  8. </where>
  9. </select>



單獨傳入數組時,foreach中的collection必須是array,不不管變量的具體名稱是什麽。比如這裏變量名為ids,
collection卻是是array

4. 傳入map

JAVA代碼:

Java代碼 技術分享圖片
  1. public boolean exists(Map<String, Object> map){
  2. Object count = getSqlSession().selectOne("com.liulanghan.exists", map);
  3. int totalCount = Integer.parseInt(count.toString());
  4. return totalCount > 0 ? true : false;
  5. }


MAPPER :

Xml代碼 技術分享圖片
  1. <select id="exists" parameterType="java.util.HashMap" resultType="java.lang.Integer">
  2. SELECT COUNT(*) FROM USER user
  3. <where>
  4. <if test="code != null">
  5. and user.CODE = #{code}
  6. </if>
  7. <if test="id != null">
  8. and user.ID = #{id}
  9. </if>
  10. <if test="idList !=null ">
  11. and user.ID in (
  12. <foreach item="guard" index="index" collection="idList"
  13. separator=","> #{guard} </foreach>
  14. )
  15. </if>
  16. </where>
  17. </select>

MAP中有list或array時,foreach中的collection必須是具體list或array的變量名。比如這裏MAP含有一個
名為idList的list,所以MAP中用idList取值,這點和單獨傳list或array時不太一樣。


5. 傳入JAVA對象

JAVA代碼:

Java代碼 技術分享圖片
  1. public boolean findUserListByDTO(UserDTO userDTO){
  2. Object count = getSqlSession().selectOne("com.liulanghan.exists", userDTO);
  3. int totalCount = Integer.parseInt(count.toString());
  4. return totalCount > 0 ? true : false;
  5. }


MAPPER :

Xml代碼 技術分享圖片
  1. <select id="findUserListByDTO" parameterType="UserDTO" resultType="java.lang.Integer">
  2. SELECT COUNT(*) FROM USER user
  3. <where>
  4. <if test="code != null">
  5. and user.CODE = #{code}
  6. </if>
  7. <if test="id != null">
  8. and user.ID = #{id}
  9. </if>
  10. <if test="idList !=null ">
  11. and user.ID in (
  12. <foreach item="guard" index="index" collection="idList"
  13. separator=","> #{guard} </foreach>
  14. )
  15. </if>
  16. </where>
  17. </select>

JAVA對象中有list或array時,foreach中的collection必須是具體list或array的變量名。比如這裏UserDTO含有一個
名為idList的list,所以UserDTO中用idList取值,這點和單獨傳list或array時不太一樣。

6.取值


由上面可以看出,取值的時候用的是#{}。它具體的意思是告訴MyBatis創建一個預處理語句參數。
使用JDBC,這樣的一個參數在SQL中會由一個“?”來標識,並被傳遞到一個新的預處理語句中,就像這樣:

Java代碼 技術分享圖片
  1. // Similar JDBC code, NOT MyBatis…
  2. String selectPerson = “SELECT * FROM PERSON WHERE ID=?”;
  3. PreparedStatement ps = conn.prepareStatement(selectPerson);
  4. ps.setInt(1,id);


可以看到這個寫法比較簡單,MyBatis為我們做了很多默認的事情,具體的寫法應該如下:

Xml代碼 技術分享圖片
  1. #{property,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler,mode=OUT,resultMap=User}

property:屬性名,即代碼傳入的變量名。
javaType:該字段在JAVA中的類型,比如int。
jdbcType:該字段在JDBC中的類型,比如NUMERIC。
typeHandler:類型處理器
mode:參數類型為IN,OUT或INOUT參數
resultMap:結果。

還好,MyBatis比較體諒我們,一般我們只需寫一個屬性名即可,如#{id},其他的如javaType和typeHandlerMybatis
會自動幫我們填好。可是這樣有時也會出問題,比如出現CLOB字段時。

由於JAVA代碼中的String類型對應的默認typeHandler為StringTypeHandler,當用String類型處理時,如果String長度超過一定長度,就會報如下錯誤:


setString can only process strings of less than 32766 chararacters

解決辦法是指定該屬性的typeHandler,如下:


#{message,typeHandler=org.apache.ibatis.type.ClobTypeHandler}

我們也可以自定義typeHandler來處理需要的數據,具體這裏詳述。

JDBC類型是僅僅需要對插入,更新和刪除操作可能為空的列進行處理。這是JDBC的需要,而不是MyBatis的。一般不需要配置

mode、resultMap一般不需要,在寫存儲過程時會用到,這裏不詳述。

7.字符串替換

一般情況下,我們采用#{}取值,產生預處理語句,但是有時我們可能不希望Mybatis來幫我們預處理,比如ORDER BY時,可以
采用如下寫法:

ORDER BY ${columnName}

這裏MyBatis不會修改或轉義字符串。而是直接拼接到SQL字符串後面。

重要:接受從用戶輸出的內容並提供給語句中不變的字符串,這樣做是不安全的。這會導致潛在的SQL註入攻擊,因此你
不應該允許用戶輸入這些字段,或者通常自行轉義並檢查。

MyBatis傳入參數與parameterType