映射器的主要元素:
本章介紹 select 元素中傳遞多個參數的處理方式。
測試類:com.yjw.demo.MulParametersTest
使用 Map 傳遞參數(不建議使用)
使用 MyBatis 提供的 Map 接口作為參數來實現。
StudentDao
/**
* 使用 Map 傳遞參數
*
* @param params
* @return
*/
List<StudentDO> listByMap(Map<String, String> params);
StudentMapper.xml
<!-- 使用 Map 傳遞參數 -->
<select id="listByMap" parameterType="map" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" /> from t_student <where> <if test="ids != null and ids.size() > 0"> AND id IN <foreach collection="ids" item="item" open="(" close=")" separator=","> #{item} </foreach> </if> <if test="name != null and name != ''"> AND name LIKE CONCAT('%', #{name}, '%') </if> <if test="sex != null"> AND sex = #{sex} </if> <if test="selfcardNo != null"> AND selfcard_no = #{selfcardNo} </if> </where> </select>
這個方法雖然簡單,但是有一個弊端:這樣設置的參數使用 Map,而 Map 需要鍵值對應,由於業務關聯性不強,造成代碼可讀性低。
使用注解方式傳遞參數(參數少時可以使用)
使用 MyBatis 的參數注解 @Param(org.apache.ibatis.annotations.Param)來實現想要的功能。
StudentDao
/**
* 使用注解方式傳遞參數
*
* @param name
* @param sex
* @return
*/
List<StudentDO> listByParamAnnotation(@Param("name") String name, @Param("sex") Sex sex);
StudentMapper.xml
把映射器的 XML 修改為無需定義參數類型。
<!-- 使用注解方式傳遞參數 -->
<select id="listByParamAnnotation" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" /> from t_student <where> <if test="name != null and name != ''"> AND name LIKE CONCAT('%', #{name}, '%') </if> <if test="sex != null"> AND sex = #{sex} </if> </where> </select>
當我們把參數傳遞給后台的時候,通過 @Param 提供的名稱 MyBatis 就會知道 #{name} 代表 name參數,參數的可讀性大大提高了。但是這回引起另一個麻煩,一條 SQL 擁有 10 個參數的查詢,如果我們都使用 @Param 方式,那么參數將十分復雜,可讀性依舊不高,不過 MyBatis 為我們提供了 JavaBean 定義參數的方式來解決這個問題。
使用 JavaBean 傳遞參數
在參數過多的情況下,MyBatis 允許組織一個 JavaBean,通過簡單的 setter 和 getter 方法設置參數,這樣就可以提高我們的可讀性。
首先,定義一個 StudentQuery 的 JavaBean
public class StudentQuery extends PageQuery {
private List<Long> ids; private String name; private Byte sex; private Long selfcardNo; // get set 方法 }
StudentDao
/**
* 根據條件獲取學生信息
*
* @param studentQuery
* @return
*/
List<StudentDO> listByConditions(StudentQuery studentQuery);
StudentMapper.xml
<!-- 根據條件獲取學生信息-->
<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" /> from t_student <where> <if test="ids != null and ids.size() > 0"> AND id IN <foreach collection="ids" item="item" open="(" close=")" separator=","> #{item} </foreach> </if> <if test="name != null and name != ''"> AND name LIKE CONCAT('%', #{name}, '%') </if> <if test="sex != null"> AND sex = #{sex} </if> <if test="selfcardNo != null"> AND selfcard_no = #{selfcardNo} </if> </where> </select>
總結
下面對各種方式加以總結,以利於我們在實際操作中的應用。
- 使用 Map 傳遞參數。因為 Map 導致業務可讀性的喪失,從而導致后續擴展和維護的困難,我們應該在實際的應用中果斷廢棄這樣的傳遞參數的方式。
- 使用 @Param 注解傳遞多個參數,這種方式的使用受到參數個數(n)的影響。當 n<= 5 時,它是最佳的傳參方式,它比用 JavaBean 更好,因為它更加直觀;當 n>5 時,多個參數將給調用帶來困難。
- 當參數個數多於5個時,建議使用 JavaBean 方式。
MyBatis 實用篇