1. 程式人生 > >mybatis 多個介面引數的註解使用方式(@Param)

mybatis 多個介面引數的註解使用方式(@Param)

1 簡介

1.1 單引數

Mybatis 中, 很多時候, 我們傳入介面的引數只有一個。 對應介面引數的型別有兩種, 一種是基本的引數型別, 一種是 JavaBean

例如在根據主鍵獲取物件時, 我們只需要傳入一個主鍵的引數即可。 而在插入, 更新等操作時, 一般會涉及到很多引數, 我們就使用 JavaBean

1.2 多引數

但是, 在實際的情況中, 我們遇到類似這樣的情況可能:

  1. 介面需要使用的引數多於一個;
  2. 介面需要使用的引數又遠少於對應 JavaBean 的成員變數, 或者需要多個 JavaBean 物件;
  3. 或者需要使用的引數對應 JavaBean 沒有相應的成員變數。

比如 獲取一段時間產生的日誌資訊, 日誌對應的 JavaBean

只有一個日期, 那我們使用該 JavaBean 就無法滿足我們的要求。

又比如我們進行模糊搜尋, 搜尋條件只有兩個, 但對應的 JavaBean50+ 個成員變數, 那建立對應的 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 &gt; #{bTime, jdbcType=TIMESTAMP} and gmt_created &lt; #{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 對應。 因此, 在此例子中傳入的引數

  1. 傳入一個 keybtime 的時間, 作為開始時間;
  2. 傳入一個 keyetime 的時間, 作為結束時間;

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 &gt; #{bTime, jdbcType=TIMESTAMP} and gmt_created &lt; #{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 中的引數進行賦值。其缺點:

  1. 手動建立 Map 這個過程很不簡潔, 看著很繁瑣。
  2. 手動對引數進行賦值, 很容易出錯。 比如本來是要 params.put("bTime", bTime) 可能會不小心寫成 params.put("bime", bTime), 但是這個時候編譯器並不會提示。

相比於 Map 方式, 使用 @Param 時, 我們在使用上就像呼叫方法一樣, 傳入對應的實際引數即可。 呼叫時基本不會出錯。

4 Github