1. 程式人生 > >mybatis學習筆記(五)- MyBatis 對映檔案(引數處理)

mybatis學習筆記(五)- MyBatis 對映檔案(引數處理)

注意:本篇筆記內容承接上一篇

引數處理

1. 單個引數&多個引數&命名引數

簡介

  1. 單個引數:mybatis不會做特殊處理,

    • #{引數名/任意名}:取出引數值。
  2. 多個引數:mybatis會做特殊處理。

    • 多個引數會被封裝成 一個map,

      • key:param1…paramN,或者引數的索引也可以
      • value:傳入的引數值
    • #{}就是從map中獲取指定的key的值;

    • 異常:
      org.apache.ibatis.binding.BindingException:
      Parameter ‘id’ not found.
      Available parameters are [1, 0, param1, param2]

    • 操作:

      • 方法:public Employee getEmpByIdAndLastName(Integer id,String lastName);
      • 取值:#{id},#{lastName}
  3. 【命名引數】:

    • 明確指定封裝引數時map的key;@Param(“id”)
      多個引數會被封裝成 一個map,
      • key:使用@Param註解指定的值
      • value:引數值
    • #{指定的key}取出對應的引數值

具體操作

  1. 在上述 EmployeeMapper 中新增
    public Employee getEmpByIdAndLastName(@Param("id")Integer id,@Param("lastName")String lastName);
  1. 在 EmployeeMapper.xml 中加入:
    <!--  public Employee getEmpByIdAndLastName(Integer id,String lastName);-->
    <select id="getEmpByIdAndLastName" resultType="
    www.xq.mybatis.bean.Employee"
    >
    select * from tbl_employee where id = #{id} and last_name=#{lastName} </select>
  2. 測試:
@Test
public void test() throws IOException{
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			Employee employee = mapper.getEmpByIdAndLastName(1,"Tom");
			System.out.println(employee);
		} finally {
			openSession.close();
		}
}

2. POJO&Map&TO

  1. 在上述 EmployeeMapper 中新增
    public Employee getEmpByMap(Map<String, Object> map);
  1. 在 EmployeeMapper.xml 中加入:
<select id="getEmpByMap" resultType="www.xq.mybatis.bean.Employee">
 		select * from ${tableName} where id=${id} and last_name=#{lastName}
 	</select>
  1. 在 EmployeeMapper.xml 中加入
@Test
public void test() throws IOException{
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			Map<String, Object> map = new HashMap<>();
			map.put("id", 2);
			map.put("lastName", "Tom");
			map.put("tableName", "tbl_employee");
			Employee employee = mapper.getEmpByMap(map);
			System.out.println(employee);
		} finally {
			openSession.close();
		}
}
  1. 總結
  • POJO:
    • 如果多個引數正好是我們業務邏輯的資料模型,我們就可以直接傳入pojo;
    • #{屬性名}:取出傳入的pojo的屬性值
  • Map:
    • 如果多個引數不是業務模型中的資料,沒有對應的pojo,不經常使用,為了方便,我們也可以傳入map
    • #{key}:取出map中對應的值
  • TO:
    • 如果多個引數不是業務模型中的資料,但是經常要使用,推薦來編寫一個TO(Transfer Object)資料傳輸物件
    • Page{
      int index;
      int size;
      }

3. 引數值的獲取

1. #與$取值區別

  1. #{}:可以獲取map中的值或者pojo物件屬性的值;
  2. ${}:可以獲取map中的值或者pojo物件屬性的值;
  3. 舉例:
    • select * from tbl_employee where id=${id} and last_name=#{lastName}
    • Preparing: select * from tbl_employee where id=2 and last_name=?
  4. 區別:
    • #{}:是以預編譯的形式,將引數設定到sql語句中;PreparedStatement;防止sql注入
    • ${}:取出的值直接拼裝在sql語句中;會有安全問題;
    • 大多情況下,我們去引數的值都應該去使用#{};
  5. 原生jdbc不支援佔位符的地方我們就可以使用${}進行取值
    比如分表、排序。。。;按照年份分表拆分
    select * from ${year}_salary where xxx;
    select * from tbl_employee order by ${f_name} ${order}

2. #{} 更豐富的用法

  • 規定引數的一些規則:
    • javaType、 jdbcType、 mode(儲存過程)、 numericScale、
      resultMap、 typeHandler、 jdbcTypeName、 expression(未來準備支援的功能);
    • jdbcType通常需要在某種特定的條件下被設定:
      在我們資料為null的時候,有些資料庫可能不能識別mybatis對null的預設處理。比如Oracle(報錯);
    • JdbcType OTHER:無效的型別;因為mybatis對所有的null都對映的是原生Jdbc的OTHER型別,oracle不能正確處理;
  • 由於全域性配置中:jdbcTypeForNull=OTHER;oracle不支援;兩種辦法
    1. #{email,jdbcType=OTHER};
    2. jdbcTypeForNull=NULL