【MyBatis学习笔记】9:分别使用Map接口,@Param注解,JavaBean对象实现多参数传递
程序员文章站
2022-03-25 13:48:36
...
预备工作
书上把多参数传递放到了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>
在主类中使用:
//调用工具类的静态方法开启并获取一个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);
//输出和善后处理...
查询结果和前面一样。
上一篇: Mybatis参数传递
下一篇: 理解前端路由 hash history