【MyBatis学习笔记】9:分别使用Map接口,@Param注解,JavaBean对象实现多参数传递

预备工作

书上把多参数传递放到了select元素那一块讲,不过这部分实际上增删查改都一样用。


新增一个用来测试的表:
这里写图片描述
Person类:

package model;

import enums.SexType;
import org.apache.ibatis.type.Alias;

@Alias("person")
public class Person {
    private Integer id;
    private String name;
    private SexType sexType;
    private String idCard;

    //getter和setter
}

在配置文件中注册枚举类型处理器:

    <!--注册类型处理器-->
    <typeHandlers>
        <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="enums.SexType"/>
    </typeHandlers>

如果缺少此处,那么使用@Param参数或JavaBean这种解放参数的方式配置解析枚举总是会报错。

映射文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.PersonMapper">
    <!--到ResultSet的映射-->
    <resultMap id="personMap" type="person">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <!--性别用枚举整数下标从数据库获取-->
        <result column="sex_type" property="sexType" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
        <result column="id_card" property="idCard"/>
    </resultMap>

    <!--通过姓氏和性别查询出一些Person-->
    <!--这里会在后面使用不同的方式做到多参数传递-->
    <!--...-->

    <!--添加一个Person,性别用枚举整数下标存入数据库,顺便使用主键回填-->
    <insert id="addPerson" parameterType="person" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO person (name, sex_type, id_card)
        VALUES (#{name}, #{sexType,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler}, #{idCard})
    </insert>
</mapper>

Mapper接口:

package mapper;

import enums.SexType;
import model.Person;

import java.util.List;
import java.util.Map;

public interface PersonMapper {
    //通过姓氏和性别查找人,可能查询到多个所以返回List<Person>
    //这里会在后面用不同的方式实现多参数传递
    //...

    //添加一个人
    int addPerson(Person person);
}

数据库表中添加的信息:
这里写图片描述

使用Map传递

将参数都放到Map里,然后把Map接口的实现类对象传递给方法。


映射器接口中添加:

    //通过姓氏和性别查找人,可能查询到多个所以返回List<Person>
    //使用Map传递多参数,参数可能有多种,但Map的value只能有一种,使用字符串是最合适的
    List<Person> findPersonByMap(Map<String, String> params);

映射文件中添加:

    <!--使用Map传递多参数,所以parameterType="map"-->
    <select id="findPersonByMap" parameterType="map" resultMap="personMap">
        SELECT
            id,
            name,
            sex_type,
            id_card
        FROM person
        WHERE name LIKE CONCAT(#{surname}, '%')
              AND sex_type = #{sexType}
    </select>

在主类中使用:

扫描二维码关注公众号,回复: 2262210 查看本文章
//调用工具类的静态方法开启并获取一个SqlSession实例
sqlSession = SqlSessionFactoryUtil.openSqlSession();
//获取映射器代理类对象
PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

//建立一个Map的实现类对象,按使用的参数名传入参数
Map<String, String> paramsMap = new HashMap<>();
paramsMap.put("surname", "刘");
//枚举对象.ordinal()获取其下标整数,再用String.valueOf将其变成数字字符串
paramsMap.put("sexType", String.valueOf(SexType.MALE.ordinal()));
//查询,传入Map的实现类对象
List<Person> personList=personMapper.findPersonByMap(paramsMap);

//输出
for(Person p:personList){
    System.out.println(p.getId()+","+p.getIdCard()+","+p.getName()+","+p.getSexType());
}

//善后处理...

查询结果:
这里写图片描述


使用Map方式传递参数不是一个好的方法,原因有下:

  • 需要在使用处查看传入了什么参数,可读性下降,业务关联性差。
  • 传参时为了多种参数都合适,Map的Value总是使用String类型,还需类型转换比较麻烦。

使用@Param注解传递

这种方式能直接在方法签名上看到传递了什么参数,可读性是最好的。当参数不多(如不超过5),并且这些参数整体没有构成业务关联(即没有整个构成一个类)时,这种方式是最佳选择。


映射器接口中添加:

    //使用@Param("参数名")来传递参数
    List<Person> findPersonByAnnotation(@Param("surname") String surname, @Param("sexType") SexType sexType);

映射文件中添加:

    <!--使用注解传递参数,这时是不涉及单独一个类型的,所以去掉parameterType属性-->
    <!--必备的属性解析(如sex_type需要解析成整数下标)需要指明,因为参数不再全是String-->
    <select id="findPersonByAnnotation" resultMap="personMap">
        SELECT
            id,
            name,
            sex_type,
            id_card
        FROM person
        WHERE name LIKE CONCAT(#{surname}, '%')
              AND sex_type = #{sexType,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler}
    </select>

在主类中使用:

//调用工具类的静态方法开启并获取一个SqlSession实例
sqlSession = SqlSessionFactoryUtil.openSqlSession();
//获取映射器代理类对象
PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

//直接传入参数查询,此时参数类型已经解放,不再必须是String
List<Person> personList = personMapper.findPersonByAnnotation("刘", SexType.MALE);

//输出和善后处理...

查询结果和前面一样。

使用JavaBean传递

当参数的数目比较多(如超过5个),或者参数之间的业务逻辑关联很强时,可以将参数整个到一个类的对象里,然后将整个对象传入。

这种方式牺牲了小部分可读性,但简化了代码,易于扩展和修改参数,并且业务逻辑性较强。


新增一个JavaBean类,其属性就是要传递的参数:

package param;

import enums.SexType;

public class MyParam {
    //注意配置文件中解析的属性名就是这里的名字,就像在值栈里一样
    private String surname;
    private SexType sexType;

    //getter和setter
}

映射器接口中添加:

    //使用JavaBean组合要传递的参数,传递JavaBean来传参
    List<Person> findPersonByJB(MyParam myParam);

映射文件中添加:

    <!--使用JavaBean来传递参数,这时parameterType=属性显然是这个JavaBean类-->
    <!--必备的属性解析(如sex_type需要解析成整数下标)需要指明,因为参数不再全是String-->
    <select id="findPersonByJB" parameterType="param.MyParam" resultMap="personMap">
        SELECT
            id,
            name,
            sex_type,
            id_card
        FROM person
        WHERE name LIKE CONCAT(#{surname}, '%')
              AND sex_type = #{sexType,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler}
    </select>

在主类中使用:

//调用工具类的静态方法开启并获取一个SqlSession实例
sqlSession = SqlSessionFactoryUtil.openSqlSession();
//获取映射器代理类对象
PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

//建立这个参数的JavaBean对象
MyParam myParam=new MyParam();
myParam.setSurname("刘");
myParam.setSexType(SexType.MALE);
//传给这个查询方法,用于查询
List<Person> personList = personMapper.findPersonByJB(myParam);

//输出和善后处理...

查询结果和前面一样。

猜你喜欢

转载自blog.csdn.net/shu15121856/article/details/81109402
今日推荐