zoukankan      html  css  js  c++  java
  • mybatis之参数处理

        mybatis的mapper接口需要和mapper映射文件进行关联,上一节已经展示接口方法的返回值是如何和mapper映射文件的resultType进行映射。这一节主要讲解接口方法的参数如何与映射文件进行关联。由于映射文件的id(及就是接口方法名称)是唯一的,因此在java代码中,方法重载不能使用。方法重载时方法名称可以相同,但是在mapper映射文件中的id是不可以有相同的。

    思考下,接口方法中的参数可能有 如下几种。

    • 单个参数
    • 多个参数

    由于每次建立工程比较复杂,可以参考第一节:mybatis入门来搭建一个简单的工程,然后来测试本节内容。

    1、单个参数


    第一节:mybatis入门测试的接口就是使用单个参数,其中mapper接口方法如下:

    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,可以随便写,都不会对查询造成实质影响。

    2、多个参数


    新添加一个mapper接口方法。主要是根据address和age查询结果。

    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>

    测试

    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);
    }

    结果

    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 有兴趣可以看下源码。

    3、特殊情况


    1、如果是业务参数模型数据,使用POJO,接口就变为一个参数,sql中使用#{}来获取数据,#{}中使用属性名称即可获取POJO对应属性的值。

    2、如果不是业务参数,但是参数很少,可以使用Param注解(上面已经提到)或者是map方式(该方式中#{}使用map的键即可获取对应键的值)。

    3、如果是非业务参数比较多,就是用一个数据传输对象TO。

    4、参数是Set集合,也是封装为map,其中key只能为collection。

    5、参数是List集合,也是封装为map,其中key只能为collection或list。

    6、参数是数组,也是封装为map,其中key只能为array。

    4、关于Param注解


    在java8中,反射获取方法参数名这一个特性被支持,因此在较新的mybatis版本中,如果程序开启-parameters编译选项,mapper接口那么就可以省略Param注解。

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

    parameters

  • 相关阅读:
    leetcode 279. Perfect Squares
    leetcode 546. Remove Boxes
    leetcode 312. Burst Balloons
    leetcode 160. Intersection of Two Linked Lists
    leetcode 55. Jump Game
    剑指offer 滑动窗口的最大值
    剑指offer 剪绳子
    剑指offer 字符流中第一个不重复的字符
    leetcode 673. Number of Longest Increasing Subsequence
    leetcode 75. Sort Colors (荷兰三色旗问题)
  • 原文地址:https://www.cnblogs.com/ye-feng-yu/p/10992111.html
Copyright © 2011-2022 走看看