Mybatis 生成SQL时自动获取 TypeHandler

2022-02-16  本文已影响0人  Java编程日记

在介绍了Mybatis是如何注册TypeHandler之后就介绍一下Mybatis是如何获取对应的TypeHandler进行类型转换的。

如果我们在Mapper.xml文件中配置某一个属性或变量的映射关系时,指定了该属性对应的javaType和jdbcType;

则Mybatis会从注册好的TypeHandler中寻找对应的javaType和jdbcType组合的TypeHandler进行处理;

这也是Mybatis最基本的获取TypeHandler进行类型转换的方式。

一、较为完整的MyBatis 中typeHandler配置

假设Mybatis配置文件中有这么一段TypeHandler的注册信息:

看这样一个UserMapper.xml定义:

<?xml version="1.0" encoding="UTF-8" ?>insert into t_user(name, age, interests) values(#{name}, #{age}, #{interests, javaType=[Ljava.lang.String;, jdbcType=VARCHAR})update t_user set name=#{name}, age=#{age}, interests=#{interests} where id=#{id}select * from t_user where id=#{id}delete from t_user where id=#{id}

1.1、配置说明

我们可以看到在id为UserResult的resultMap中,

我们定义了一个对应字段interests的映射关系,并且定义了其javaType为“[Ljava.lang.String;”,jdbcType为VARCHAR,

这个时候Mybatis就会到已经注册了的TypeHandler中寻找到能处理javaType和jdbcType对应的类型转换的TypeHandler来进行处理。

在这里就会找到我们注册的StringArrayTypeHandler。

在上面id为insertUser的insert语句中,

我们也为变量interests指定了它的javaType和jdbcType属性,这时候Mybatis也会寻找javaType和jdbcType对应的TypeHandler。

上面这样定义是Mybatis最基本也是最完整地获取到对应的TypeHandler的方法。

1.2、代码使用测试

这里我们来对UserMapper(它的代码我就不贴出来了,有Mybatis基础的都应该知道它的代码)的findById来做一个测试:

@TestpublicvoidtestFind(){    SqlSession sqlSession = sqlSessionFactory.openSession();try{        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);        User user = userMapper.findById(20);        System.out.println(user);    }finally{        sqlSession.close();    }  }

其输出结果如下:

User [age=30, id=20, interests=[Music, Movie, NBA], name=张三]

我们可以看到Mybatis已经把我们存放在数据库中VARCHAR类型的字段interests转换为User类字符串数组类型的interests属性,这说明我们定义的StringArrayTypeHandler发生作用了。

除了上面的完整指定一个变量对应的javaType和jdbcType,让Mybatis能够完美的找到对应的TypeHandler之外。我们平时书写配置的时候,可能会少写部分配置。

二、只指定变量对应的javaType类型

这个时候Mybatis会拿着这个javaType和jdbcType为null的组合到注册的TypeHandler中寻找对应的TypeHandler。

2.1、测试一:TypeHandler 注册的 jdbcType 不为NULL

不动StringArrayTypeHandler的注册信息,把我们的UserMapper.xml改为如下形式:

<?xml version="1.0" encoding="UTF-8" ?>select * from t_user where id=#{id}

这时候再运行上面的测试程序,输出结果如下:

User [age=30, id=20, interests=null, name=张三]

我们可以看到输出的interests为null,这说明Mybatis没有使用我们定义的StringArrayTypeHandler来转换interests。

2.2、测试二:TypeHandler 注册的 jdbcType 为null

UserMapper.xml还像上面那样定义,但是也只指定javaType属性来注册我们的StringArrayTypeHandler,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>...........

这个时候再运行上面的测试代码,输出结果如下:

User [age=30, id=20, interests=[Music, Movie, NBA], name=张三]

这是因为我们是以javaType和null注册的StringArrayTypeHandler,然后在需要转换interests时又是以相同的javaType和null来寻找的,所以就会找到我们注册的StringArrayTypeHandler来进行类型转换。

三、只指定变量对应的jdbcType类型

这个时候Mybatis会利用我们指定的返回类型和对应的属性,取该属性在返回类型中对应的javaType,之后再拿着该javaType和我们指定的jdbcType到注册的TypeHandler中获取对应的TypeHandler。

3.1、测试一:根据返回值类型分析 javaType

保持之前指定javaType和jdbcType的方式注册StringArrayTypeHandler,然后在定义interests变量的时候不指定javaType,只指定jdbcType。

这个时候UserMapper.xml如下所示:

<?xml version="1.0" encoding="UTF-8" ?>select * from t_user where id=#{id}

这个时候继续运行上面的测试代码,输出结果如下:

User [age=30, id=20, interests=[Music, Movie, NBA], name=张三]

这个时候Mybatis是这样获取TypeHandler的:

首先它发现我们的interests没有指定javaType;

这个时候它就会通过我们指定的类型User和属性interests获取User类的interests属性对应的java类型,即String数组;

再拿着获取到的javaType和我们指定的jdbcType即VARCHAR去寻找对应的TypeHandler,

这个时候就找到了我们之前以String数组和VARCHAR注册好的StringArrayTypeHandler来处理interests的类型转换。

四、javaType类型和jdbcType类型都不指定

这个时候Mybatis会以第三小节中的方式(三、只指定变量对应的jdbcType类型)获取到对应的javaType类型,然后再以第二小节的方式(只指定变量对应的javaType类型)获取到对应的TypeHandler。

五、直接在Mapper文件中通过 typeHandler 属性指明 typeHandler

这个时候Mybatis就会使用该用户自己指定的TypeHandler来进行类型转换,而不再以javaType和jdbcType组合的方式获取对应的TypeHandler。

5.1、配置示例

<?xml version="1.0" encoding="UTF-8" ?>select * from t_user where id=#{id}

运行上面的测试代码,输出结果:

User [age=30, id=20, interests=[Music, Movie, NBA], name=张三]

这是因为我们指定了进行interests字段的映射关系时使用StringArrayTypeHandler来进行类型转换。

当指定了某一个字段或变量进行映射关系时所使用的TypeHandler时,Mybatis在需要进行类型转换时就使用给定的TypeHandler进行类型转换,而不会再通过javaType和jdbcType的组合去注册好的TypeHandler中寻找对应的TypeHandler。

上一篇下一篇

猜你喜欢

热点阅读