【Mybatis】Mybatis的小坑,xxMapper.java里的返回类型是编译期有效的,而xxMapper.xml的返回类型是运行期有效的,程序能够运作实际依赖的是resultType类型。
有一个EmpMapper.java,里面获取全部数据的fetchAll函数是这样写的:
@Mapper public interface EmpMapper { List<Emp> fetchAll(); }
而对应的Empmapper.xml会是这样:
<mapper namespace="com.hy.dao.EmpMapper"> <select id="fetchAll" resultType="com.hy.entity.Emp"> select id,name,profile from emp430_1 </select> </mapper>
现在,函数的返回类型和resultType类型一致,运行自然没什么问题,但当函数的返回类型改变了,比如从Emp变成Emp2,而resultType忘记改变时,在编译期是不会出错的,也就是说idea不会报错。
但真正运行起来会出现ClassCastException,即类型转换异常。
由此可以知道,Mybatis以反射方式将resultType指定的类型实例化,塞入列表结构后,实际是以Object形式放进去的,用到的时候会根据函数定义进行强转,当函数的返回类型和resultType类型一致,强转自然没问题;当类型不一致,强转便会导致ClassCastException。
虽然是疏忽导致了错误,但因此窥见了MyBatis的背后运作也算歪打正着。
END