美文网首页Java 杂谈我爱编程
MyBaits | 映射文件之参数处理

MyBaits | 映射文件之参数处理

作者: EclipseO2 | 来源:发表于2018-07-26 14:48 被阅读3次

    一、MyBaits的增删改查

    1. 介绍

    输入映射

    这里我先介绍一下输入映射,是在映射文件中通过 parameterType 指定输入参数的类型,类型可以是简单类型、HashmapPOJO 的包装类型。在实际操作中,一般我们会在 parameterType 属性中传入 POJO 的类名。如果是通过输入条件进行查询,我们只需要传入对应的 POJO 中的属性即可

    输出映射

    输出映射就是 sql 语句查询结束后返回的结果类型,在映射文件中通过 resultType 来显示输出的结果类型,不过一般可以不用设置 resultType,MyBatis 会自己帮我们输出。另外还可以使用 resultMap,这种配置方式可以用于各种复杂的映射方式,比如一对多,多对多等等,在后面的文章中会加以介绍

    2. 使用 resultType 配置实现增删改查

    ①.首先我们定义一个 POJO 类:Employee.java

    public class Employee {
    
        private Integer id;
        private String lastName;
        private String email;
        private Integer gender;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
            ......
    }
    

    ②. 然后我们定义一个接口类:EmployeeMapper.java,该接口包含了对 Employee 的增删改查操作

    public interface EmployeeMapper {
            
        public void addEmployee(Employee employee);
        
        public void updateEmployee(Employee employee);
        
        public long deleteEmployee(Integer id);
        
        public Employee getEmployee(Integer id);
        
    }
    

    ③. 配置 EmployeeMapper.xml,这里我就只对增加操作加以说明,其他三种操作与之类似

    <mapper namespace="edu.just.mybatis.dao.EmployeeMapper">
        <select id="getEmployee" resultType="edu.just.mybatis.bean.Employee">
            select id, last_name lastName, email, gender from employee where id = #{id}
        </select>
    </mapper>
    
    • namespace:指定为你要实现的接口的全类名
    • id:唯一标识 resultType: 返回值类型
    • parameterType:是传入的参数的类型,可以使用别名,如果返回的是一个集合, 则写集合中元素的类型,比如 Employee, mybaits 会自动帮你把该类的对象放入集合中并返回
    • resultType:返回查询结果的类型,没有指定别名的情况下,使用全类名,当然也可以省略

    ④. 写一个测试语句,使用接口定义的方法

    @Test
    public void testGetEmployee() throws IOException {
        //1. 获取 sqlSessionFactory 对象
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactoty();
        
        //2. 获取 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
            
        try {
            //3. 获取接口的实现类对象, 会为接口自动创建一个代理对象, 代理对象去执行增、删、改、查
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
            Employee employee = employeeMapper.getEmployee(1);
            System.out.println(employee);
        } finally {
            sqlSession.close();
        }
    }
    

    这里需要注意的是:如果涉及到对数据库数据本身的操作,针对增删改,每次执行完 sql 语句都需要提交数据,如果只是查询操作,则可以不必提交

    1. 如果创建 openSession() 没有加参数,则在执行 sql 的语句后提交数据,可以使用 sqlSession.commit()
    2. 如果创建 openSession(true), 则不需要提交数据

    3. 其他情况

    3.1 获取自增主键的值

    在配置文件中将 useGeneratedKeys 属性设置为 true,同时 keyProperty 属性指定将获取的主键值赋给 JavaBean 的哪个属性

    <insert id="addEmployee" parameterType="Employee" useGeneratedKeys="true" keyProperty="id">
        Insert into employee(last_name, email, gender) values(#{lastName}, #{email}, #{gender})
    </insert>
    

    该配置表示将主键值赋给 Employee 的 id 属性,在测试文件中如果输出 id,即为当前查询结果的主键值

    3.2 返回 List 集合的操作

    首先在接口类中添加返回集合的方法

    public List<Employee> getEmployees(String lastName);
    

    然后在 sql 映射文件中配置,此时 resultType 的类型依旧是 Employee,因为对应的是集合中参数的类型

    <select id="getEmployees" resultType="Employee">
        select * from employee where last_name like #{lastName}
    </select>
    

    输出如下

    [Employee [id=7, lastName=null, email=lkj@123.com, gender=1], 
    Employee [id=13, lastName=null, email=lkj@123.com, gender=2], 
    Employee [id=14, lastName=null, email=lkj@123.com, gender=2], 
    Employee [id=15, lastName=null, email=lkj@123.com, gender=2], 
    Employee [id=16, lastName=null, email=lkj@123.com, gender=2]]
    
    3.3 返回一个封装多个记录的 Map 集合

    @MapKey() 告诉 mybatis 封装这个 map 时候使用哪个POJO 属性作为 key

    @MapKey("id")
    public Map<Integer, Employee> getEmployee3(Integer id);
    

    配置 sql 映射文件,注意此时 resultType 类型依然是 Employee,即表示返回的类型依旧是 Employee

    <select id="getEmployee3" resultType="Employee">
        select id, last_name lastName, email, gender from employee where id > #{id}
    </select>
    

    输出

    {16=Employee [id=16, lastName=lkj, email=lkj@123.com, gender=2], 
    17=Employee [id=17, lastName=lkj, email=lkj@123.com, gender=2], 
    2=Employee [id=2, lastName=Peter, email=peter@qq.com, gender=1], 
    19=Employee [id=19, lastName=lkj, email=lkj@123.com, gender=2], 
    20=Employee [id=20, lastName=lkj, email=lkj@123.com, gender=2]}
    

    二、对参数进行处理

    1. 传入单个参数

    传入单个参数时,${xxx} 里面的参数名和属性名无关,比如你占位符设置为 #{id},此时当然可以查询出结果。但是如果你设置为 #{id123},同样查询出结果, 但是如果什么都不填, 则会报错

    <select id="getEmployee" resultType="edu.just.mybatis.bean.Employee">
           select id, last_name lastName, email, gender from employee where id = #{id123} 
    </select>
    
    2. 传入多个参数

    我们先来看一个情景,如果需要传入 idlastName 两个参数

    public Employee getEmployee2(Integer id, String lastName);
    

    sql 的配置文件是这样设置的

    <select id="getEmployee2" resultType="employee">
        select id, last_name lastName, email, gender from employee where 
          id = #{id} and last_name = #{lastName}
    </select>
    

    此时会出这样的错误:Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]

    原因就是当 sql 语句传入不止一个参数时, MyBatis 会做特殊处理, 多个参数会被封装到一个 Map 对象 map 中,当你每传入一个参数,map 对象会将参数以键为 param1, param2...paramN,值为你 传入的参数的值 的形式来保存数据,此时 ma

    解决方案

    方案一
    我们以上述的例子为例,我们可以直接传入 #{param1},#{param2} 等参数

    <select id="getEmployee2" resultType="employee">
        select id, last_name lastName, email, gender from employee where 
            id = #{param1} and last_name = #{param2}
    </select>
    

    方案二
    我们在接口定义的方法处,使用 @Param() 标注给方法中的参数起名字,其实本质上也是放在 Map 和对象 map 中

    public Employee getEmployee2(@Param("id")Integer id, @Param("lastName")String lastName);
    

    我们可以这样给传入的参数赋值,这时 map 中的 key 变为了 id, lastName, param1, param2。因此我们可以直接在 #{} 中传入我们自己命名的值。当然就算传入 #{param1} 之类的也是可以的。

    <select id="getEmployee2" resultType="employee">
        select id, last_name lastName, email, gender from employee where 
            id = #{id} and last_name = #{lastName}
    </select>
    

    三、${} 和 #{} 的区别

    #{}:是以预编译的形式,将参数设置到 sql 语句中,多用于 where 语句后面的填充位,
    ${}:取出的值直接拼接在 sql 语句中,多用于分表的 sql 语句,会有线程安全的问题

    关于 #{} 的使用我不加以赘述,下面举例说明 ${} 用于分表的操作语句

    select * from ${year}_table where xxx
    select * from table order by ${xxx} ${xxx}
    

    相关文章

      网友评论

        本文标题:MyBaits | 映射文件之参数处理

        本文链接:https://www.haomeiwen.com/subject/chtbmftx.html