解决mapper.xml中resultType映射类型的问题
作者:内涵无处不在
mapper.xml中resultType映射类型问题
记录一下在公司开发中遇到的问题
在使用 mapper.xml 进行编写时 resultMap=“String” String竟然引用不进去,在程序中标红,别的mapper中也映射过但是别的就好使,然后重新启动的时候代码执行报错
<select id="queryAreaBy" parameterType="String" resultType="String"> select SUM(area) as area from tb_forward_area where server_time = #{serverTime} and region_code like concat('%',#{regionCode},'%') and del_flag='0' </select>
这时需要 在resultType 中引入绝对路径
<select id="queryAreaBy" parameterType="String" resultType="java.lang.String" > select SUM(area) as area from tb_forward_area where server_time = #{serverTime} and region_code like concat('%',#{regionCode},'%') and del_flag='0' </select>
代码也不报错了也可以正常使用了,第二天继续编写项目时,试了下把 java.lang. 这个路径删了他也好使了,但是在同一个mapper中别的SQL想使用String或者Long类型的还需要引入绝对路径
mybatis Mapper接口映射Mapper.xml代码分析
我们在使用mybatis时,会用到Mapper接口映射Mapper.xml,具体怎么映射的我们不知道。只知道要这么用,下面我们开始分析mybatis代码。
在分析具体代码时,我们有必要先看一下jdk动态代理。
简单点说:jdk动态代理,可以让我们在不实现接口的情况下,去动态生成接口的实现。
传统上我们要去实现接口,都会创建具体的实现类.java, 而jdk动态代理,可以让我们不用创建具体的实现类.java,就可以生成接口实现。
代码如下:
/** * 代理工具方法,可以为任意接口生成任意实例代理,该方式使用在了mybatis的Mapper接口映射Mapper.xml中,具体在 MapperProxyFactory * @param tClass * @param invocationHandler * @param <T> * @return */ public <T> T test4(Class<T> tClass, InvocationHandler invocationHandler) { T t = (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class[] {tClass},invocationHandler); return t; } @Test public void test6() { UserMapper userMapper = test4(UserMapper.class, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("查询所有"); return null; } }); userMapper.getAll(); }
UserMapper为接口,上面的代码就直接生成了UserMapper的实现。
执行结果:
可以看到我们已经成功生成了UserMapper的实现,方法也正常执行了。
mybatis正是使用了该特性进行Mapper接口与Mapper.xml进行映射。
mybatis代码如下:
具体方法映射在mapperProxy的invoke方法中完成。 如下
进而到MapperMethod中,如下:
然后是SqlCommand,如下:
继续往下:
statementId就是我们的接口完全限定名加方法名。获取对应的MappedStatement后,进行下一步处理。这里我们肯定会想,这个MappedStatement是怎么生成的,生成就是在解析Mapper.xml时生成的,代码如下:
上面的id就是namespace+ select,update,delete,insert的id。
从这里也可以看到我们Mapper.xml的namespace必须的是Mapper接口的完全限定名,select,update,delete,insert的id也必须是接口的方法名。否则使用接口去映射时就会报错。
xml解析完毕后,就调用如下方法,生成接口的代理类,并将接口中方法上的mybatis注解,生成MappedStatement,代码如下
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。