mybatis之參數處理

    mybatis的mapper接口須要和mapper映射文件進行關聯,上一節已經展現接口方法的返回值是如何和mapper映射文件的resultType進行映射。這一節主要講解接口方法的參數如何與映射文件進行關聯。因爲映射文件的id(及就是接口方法名稱)是惟一的,所以在java代碼中,方法重載不能使用。方法重載時方法名稱能夠相同,可是在mapper映射文件中的id是不能夠有相同的。html

思考下,接口方法中的參數可能有 以下幾種。java

  • 單個參數
  • 多個參數

因爲每次創建工程比較複雜,能夠參考第一節:mybatis入門來搭建一個簡單的工程,而後來測試本節內容。sql

一、單個參數


第一節:mybatis入門測試的接口就是使用單個參數,其中mapper接口方法以下:apache

public interface PersonMapper
{
    Person getPerson(Integer id);
}

在mapper映射文件中:數組

<select id="getPerson" resultType="com.yefengyu.mybatis.entity.Person">
    select * from person where id = #{id}
</select>

其中上面的 #{id} 中的 id,能夠隨便寫,都不會對查詢形成實質影響。mybatis

二、多個參數


新添加一個mapper接口方法。主要是根據address和age查詢結果。app

public interface PersonMapper
{
   List<Person> getPersons(String address, Integer age);
}

而後編寫mapper映射文件。測試

<select id="getPersons" resultType="com.yefengyu.mybatis.entity.Person">
    select id, first_name firstName, last_name lastName, age, email, address from person where address = #{address} and age > #{age}
</select>

測試ui

public static void main(String[] args)
        throws IOException
{
    InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
    List<Person> personList = mapper.getPersons("beijing", 30);
    System.out.println(personList);
}

結果spa

Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'address' not found. Available parameters are [arg1, arg0, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'address' not found. Available parameters are [arg1, arg0, param1, param2]
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)

分析:mybatis對於多個參數會特殊處理,把多個參數封裝爲map,key默認取值爲param1, param2,依次類推,value取實際的值。

根據這個原理,咱們把

<select id="getPersons" resultType="com.yefengyu.mybatis.entity.Person">
    select id, first_name firstName, last_name lastName, age, email, address from person where address = #{address} and age > #{age}
</select>

改成

<select id="getPersons" resultType="com.yefengyu.mybatis.entity.Person">
    select id, first_name firstName, last_name lastName, age, email, address from person where address = #{param1} and age > #{param2}
</select>

再次測試能夠獲得正常結果。

    上面的方式雖然解決了多個參數的傳遞問題,可是對於書寫和閱讀都有障礙,最好是使用命名參數,指定封裝map的key,實現很簡單,在接口方法的參數聲明處使用Param註解,指定值做爲map的key.

public interface PersonMapper
{
   List<Person> getPersons(@Param("address") String address, @Param("age") Integer age);
}
<select id="getPersons" resultType="com.yefengyu.mybatis.entity.Person">
    select id, first_name firstName, last_name lastName, age, email, address from person where address = #{address} and age > #{age}
</select>

這樣就能夠實現多個參數傳遞。

源碼位置:org.apache.ibatis.reflection.ParamNameResolver 有興趣能夠看下源碼。

三、特殊狀況


一、若是是業務參數模型數據,使用POJO,接口就變爲一個參數,sql中使用#{}來獲取數據,#{}中使用屬性名稱便可獲取POJO對應屬性的值。

二、若是不是業務參數,可是參數不多,可使用Param註解(上面已經提到)或者是map方式(該方式中#{}使用map的鍵便可獲取對應鍵的值)。

三、若是是非業務參數比較多,就是用一個數據傳輸對象TO。

四、參數是Set集合,也是封裝爲map,其中key只能爲collection。

五、參數是List集合,也是封裝爲map,其中key只能爲collection或list。

六、參數是數組,也是封裝爲map,其中key只能爲array。

四、關於Param註解


在java8中,反射獲取方法參數名這一個特性被支持,所以在較新的mybatis版本中,若是程序開啓-parameters編譯選項,mapper接口那麼就能夠省略Param註解。

添加位置:File->Settings->Build,Execution,Deployment->Java Compiler下的Additional command line parameters選項中添加-parameters。

parameters

相關文章
相關標籤/搜索