@
1 簡介
1.1 單參數
在 Mybatis 中, 很多時候, 我們傳入接口的參數只有一個。 對應接口參數的類型有兩種, 一種是基本的參數類型, 一種是 JavaBean。
例如在根據主鍵獲取對象時, 我們只需要傳入一個主鍵的參數即可。 而在插入, 更新等操作時, 一般會涉及到很多參數, 我們就使用 JavaBean。
1.2 多參數
但是, 在實際的情況中, 我們遇到類似這樣的情況可能:
- 接口需要使用的參數多於一個;
- 接口需要使用的參數又遠少於對應 JavaBean 的成員變量, 或者需要多個 JavaBean 對象;
- 或者需要使用的參數對應 JavaBean 沒有相應的成員變量。
比如 獲取一段時間產生的日志信息, 日志對應的 JavaBean 只有一個日期, 那我們使用該 JavaBean 就無法滿足我們的要求。
又比如我們進行模糊搜索, 搜索條件只有兩個, 但對應的 JavaBean 有 50+ 個成員變量, 那創建對應的 JavaBean 就過於浪費了。
對此, 我知道的有如下幾種方法
2 多個接口參數的兩種使用方式
2.1 Map 方法(不推薦)
Map
方法的使用很簡單, 就是將對應的參數以 key-value 的方式存儲, key 對應 SQL 中的參數名字, value 對應需要傳入的參數值。
以獲取一段時間內存儲的用戶為例
2.1.1 創建接口方法
/**
* 獲取一段時間內的用戶
* @param params
* @return
*/
List<Student> selectBetweenCreatedTime(Map<String, Object> params);
該方法返回的是多個記錄, 因此使用 List
作為返回值。
2.1.2 配置對應的SQL
<select id="selectBetweenCreatedTime" parameterType="java.util.Map" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from student
where gmt_created > #{bTime, jdbcType=TIMESTAMP} and gmt_created < #{eTime, jdbcType=TIMESTAMP}
</select>
id 與 之前創建的方法名一樣。
2.1.3 調用
@Test
public void testSelectBtweenCreatedTimeMap() {
Map<String, Object> params = new HashMap<>();
Calendar bTime = Calendar.getInstance();
// month 是從0~11, 所以9月是8
bTime.set(2018, Calendar.AUGUST, 29);
params.put("bTime", bTime.getTime());
Calendar eTime = Calendar.getInstance();
eTime.set(2018,Calendar.SEPTEMBER,2);
params.put("eTime", eTime.getTime());
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.openSession();
StudentMapper studentMapper = (StudentMapper) sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.selectBetweenCreatedTime(params);
for (int i = 0; i < students.size(); i++) {
System.out.println(students.get(i));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
調用方法很簡單, 傳入相應的 Map 參數即可。 此時, Map 中的 key 對應。 因此, 在此例子中傳入的參數
- 傳入一個 key 為 btime 的時間, 作為開始時間;
- 傳入一個 key為 etime 的時間, 作為結束時間;
2.2 @Param 方法(推薦)
@Param 方法就是使用注解的方式,
2.2.1 創建接口方法
/**
* 獲取指定時間內的對象
* @param pbTime 開始時間
* @param peTime 結束時間
* @return
*/
List<Student> selectBetweenCreatedTimeAnno(@Param("bTime")Date pbTime, @Param("eTime")Date peTime);
@Param("bTime") 就是告訴 mybatis , 參數 pbTime 在 SQL 語句中用 bTime 作為 key。
也就是說, mybatis 幫我們完成了調用時, 類似 params.put("bTime", pbTime) 這個過程。
2.2.2 配置 SQL 語句
<select id="selectBetweenCreatedTimeAnno" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from student
where gmt_created > #{bTime, jdbcType=TIMESTAMP} and gmt_created < #{eTime, jdbcType=TIMESTAMP}
</select>
此處的 bTime 對應** @Param("bTime")** 中的 bTime, 需要完全一致。
eTime 也是一樣。
2.2.3 調用
在調用時, 不需要創建 Map
了, 只需要按參數提示傳入對應的實際參數即可。
@Test
public void testSelectBtweenCreatedTimeAnno() {
Map<String, Object> params = new HashMap<>();
Calendar bTime = Calendar.getInstance();
// month 是從0~11, 所以9月是8
bTime.set(2018, Calendar.AUGUST, 29);
Calendar eTime = Calendar.getInstance();
eTime.set(2018,Calendar.SEPTEMBER,2);
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.openSession();
StudentMapper studentMapper = (StudentMapper) sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.selectBetweenCreatedTimeAnno(bTime.getTime(), eTime.getTime());
for (int i = 0; i < students.size(); i++) {
System.out.println(students.get(i));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
3 @Param 的優勢
Map 方式的缺點就是需要手動創建 Map
, 並對 SQL 中的參數進行賦值。其缺點:
- 手動創建
Map
這個過程很不簡潔, 看着很繁瑣。 - 手動對參數進行賦值, 很容易出錯。 比如本來是要 params.put("bTime", bTime) 可能會不小心寫成 params.put("bime", bTime), 但是這個時候編譯器並不會提示。
相比於 Map
方式, 使用 @Param 時, 我們在使用上就像調用方法一樣, 傳入對應的實際參數即可。 調用時基本不會出錯。
4 Github
相應代碼, 可以訪問 我的Github-helloMybatis
一起學 mybatis
你想不想來學習 mybatis? 學習其使用和源碼呢?那么, 在博客園關注我吧!!
我自己打算把這個源碼系列更新完畢, 同時會更新相應的注釋。快去 star 吧!!