1. 程式人生 > >mybatis學習筆記之——mybatis配置資訊中引數值的處理

mybatis學習筆記之——mybatis配置資訊中引數值的處理

引數值的處理:

單個引數:mybatis不會做特殊處理
    #{引數名}:取出引數值

多個引數:mybatis會做特殊處理。
    多個引數會封裝成一個map,
        key:param1.....paramN,或者引數索引也可以
        value:傳入的引數值
    #{}就是從map中獲取指定的key的值。

命名引數:明確指定封裝引數時map的key:@Param("id")
    多個引數被封裝成一個map
    key:使用@Param指定的值
    value:引數值
    #{指定的key}取出對應的引數值。

POJO:
如果多個引數正好是我們業務邏輯的資料模型,我們就可以直接傳入pojo;
    #{屬性名}:取出傳入的pojo的屬性值

Map:
如果多個引數不是業務模型中的資料,沒有對應的pojo,不經常使用,為了方便,我們也可以傳入map
    #{key}:取出map中對應的值

TO:
如果多個引數不是業務模型中的資料,但是經常要使用,推薦來編寫一個TO(Transfer Object)資料傳輸物件
Page{
    int index;
    int size;
}

下面列出例項來說明:

public Employee getEmp(@Param("id")Integer id, String lastName);
    取值:id ==> #{id/param1}
          lastName ==> #{param2}

public Employee getEmp(Integer id, @Param("e")Employee emp);
    取值:id ==> #{param1}
          lastName ==> #{param2.lastName/e.lastName}

特別注意:如果是Collection(List、Set)型別或者是陣列,也會特殊處理。也是把傳入的list或者陣列封裝在map中。
key:Collection(collection),如果是List還可以使用這個key(list),
陣列(array)
public Employee getEmpById(List<Integer> ids);
    取值(取出第一個id的值):id ==> #{list[0]}

 

其中獲取引數值:

#{ }:可以獲取map中的值或者pojo物件屬性的值
${ }:可以獲取map中的值或者pojo物件屬性的值
    區別:#{ }是以預編譯的方式將引數設定到sql語句中;類似PreparedStatement;防止sql注入。
          ${ }是取出的值直接拼裝在sql語句中;會有安全隱患。
          大多情況下我們取引數值使用#{ };有些情況也會使用${ }(原生jdbc不支援佔位符或者預編譯的)。 

#{ }更豐富的用法: 規定引數的一些規則:

          javaType、jdbcType、mode(儲存過程)、numericScale、resultMap、typeHandler、jdbcTypeName、expression

jdbcType通常需要在某種特定的條件下被配置:在我們資料為null的時候,有些資料庫可能不能識別mybatis對null的預設處理。比如Oracle(報錯)。錯誤資訊:JdbcType OTHER:無效的型別;因為mybatis對所有的null都對映的是原生jdbc的OTHER型別,Oracle不能正確處理。

解決方法有兩種:

1、在SQL語句中做修改(假如email為空)

<insert id="addEmp" parameterType="com.test.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO tbl_employee(last_name,email,gender) VALUES (#{lastName},#{email,jdbcType=NULL},#{gender})
</insert>

2、在全域性配置檔案中做修改

<settings>
    <setting name="jdbcTypeForNull" value="true"/>
</settings>