核心转换方法:
/**
* <p>
* 返回一个不带名称的非特殊参数.
* 多个参数使用命名规则命名.
* 除了默认名称外,此方法还添加了泛型名称 (param1, param2,
* ...).
* </p>
*
* @param args
* the args
* @return the named params
*/
public Object getNamedParams(Object[] args) {
final int paramCount = names.size();
if (args == null || paramCount == 0) {
return null;
} else if (!hasParamAnnotation && paramCount == 1) {
// 如果没有@Param注解并且参数数量为1,那么直接返回
Object value = args[names.firstKey()];
return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);
} else {
final Map<String, Object> param = new ParamMap<>();
int i = 0;
for (Map.Entry<Integer, String> entry : names.entrySet()) {
param.put(entry.getValue(), args[entry.getKey()]);
// add generic param names (param1, param2, ...)
final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
// ensure not to overwrite parameter named with @Param
if (!names.containsValue(genericParamName)) {
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
}
}
1、单个参数
// 单个参数
private static void test1() throws IOException {
String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper personMapper = session.getMapper(PersonMapper.class);
Person person = personMapper.getPersonById("20210420172645864088a2a1ba11eb886d525400146075");
System.out.println(person);
}
}
args 为执行mapper方法中的参数数组
判断是否为集合或者数组
可以看到该object既不是集合也不是数组,直接什么都不干就返回
2、多个参数
// 多个参数
private static void test2() throws IOException {
String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper personMapper = session.getMapper(PersonMapper.class);
Person person = personMapper.getPersonByNameAndAage("李四", "20");
System.out.println(person);
}
}
@Select("select * from person where name = #{name} and age = #{age}")
Person getPersonByNameAndAage(String name, String age);
args 为执行mapper方法中的参数数组
循环names的map,对param进行put
得到一个参数map
3、多个参数,加上@Param注解
// 多个参数
private static void test3() throws IOException {
String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper personMapper = session.getMapper(PersonMapper.class);
Person person = personMapper.getPersonByNameAndAage2("李四", "20");
System.out.println(person);
}
}
@Select("select * from person where name = #{name} and age = #{age}")
Person getPersonByNameAndAage2(@Param("name") String name,@Param("age") String age);
这时候 names的map的key就为@Param设置的参数名,并且循环names的map,对param进行put
得到一个参数map
综上,都将参数统一转换成param1、param2.......
4、进行参数转换
根据动态sql对象转换成对应的属性名称
@Select("select * from person where name = #{name} and age = #{age}")
Person getPersonByNameAndAage2(@Param("name") String name,@Param("age") String age)
该动态sql中的property就是sql中#{}的两个参数
@Select("select * from person where name = #{name} and age = #{age}")
这样就实现了将sql语句转换成了java对象中的属性property,这时就可以使用java语言处理sql语句,根据property去获取上面获取到的参数map中的值进行占位替换
5、接着将进入类型处理器对传入的参数进行相应类型的解析
类型处理器抽象类,封装了各种类型的处理器,进行相应类型的处理转换操作
由于我传入的都是String类型,那么就会进入String类型处理器StringTypeHandler,然后进行设置参数
传入一个对象参数
// 多个参数
private static void test4() throws IOException {
String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper personMapper = session.getMapper(PersonMapper.class);
Person param = new Person();
param.setName("李四");
param.setAge("20");
Person person = personMapper.getPersonByNameAndAage3(param);
System.out.println(person);
}
}
@Select("select * from person where name = #{person.name} and age = #{person.age}")
Person getPersonByNameAndAage3(@Param("person") Person person);
这时拿到的是一个UnknownTypeHandler
然后设置参数
总结:1、先解析参数名称 --> 2、将sql中的占位参数转换成对应的java对象中的property属性 --> 3、根据参数的类型进行设置参数