在mybatis中,ResultSetHandler在收集JDBC返回的结果后需要转换成对应的Bean对象,其实映射的原理基本大家都能想到使用的时候java中的反射机制,但是在Mybatis中,提供了一个更加强大的对象,就是MetaObject,使用这个对象不仅对Bean中的属性赋值、取值都十分简单,同时还能对嵌套对象进行操作。
简单使用
可以看到,整个MateObject让设置和获取类的属性更加方便了,在工作中可以当做工具类直接使用。
底层结构
MetaObject -> BeanWapper -> MetaClass -> Reflector
可递归操作 无法递归操作 可递归操作 无法递归操作
① MetaObject 可以操作嵌套属性
② BeanWapper 只能操本类的属性
③ MetaClass 可以操作嵌套的set、get方法
④ Reflector 只能操作本类的set、get方法
从构造方法中可以看到依赖的顺序
MetaObject:
BeanWapper :
MetaClass :
分词器
当需要集合中某个元素的某个属性的时候,表达式需要这样写:list[0].user.name,这个时候就需要一个比较重要的组件去判断是否直接获取属性,还是递归生成对象了,它就是PropertyTokenizer分词器。
里面存在四个属性:
① name :当前获取的属性名称,移除下标
② indexedName:当前获取属性全部的名称
③ index:下标值
④ children:子元素全部
源码分析:
这里只分析getValue()方法,进入之后,会直接使用分词器进行分词,当发现存在下一个节点的时候,创建一个新的节点meateObject,调用新节点的getValue()方法,否则直接调用BeanWrapper的获取。
BeanWrapper中,get()方法,当存在集合的时候,使用获取集合的值,不是集合的时候,直接获取Bean的值。
如果name为空,直接返回集合,否则递归调用metaObject的getValue()
然后根据分词器的下表,返回元素
当为bean的属性的时候,直接返回调用MeteClass的反射方法,获取属性的值
以上就是MeteObject的基本使用和基本流程,相对而言比较简单,记录下来主要是以后自己要写相关工具的时候,可以参照其实现方法,甚至可以直接拿过来用就行了,因为是底层的工具类所以很少的依赖其它的东西。