MyBatis中的MetaObject是MyBatis中的反射工具,可以使用MetaObject完成获取值和设值的任务
本文基于MyBatis 3.5.7
作用
根据路径获取值和设值
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| User user = buildUser();
MetaObject metaObject = SystemMetaObject.forObject(user);
Object value = metaObject.getValue("tags[0].creator.name");
System.out.println(value);
metaObject.setValue("tags[0].creator.name","CreatorName");
value = metaObject.getValue("tags[0].creator.name");
System.out.println(value);
|
结构

这里面最主要的就是ObjectWrapper,而ObjectWrapper主要分为以下几类
- Bean Wrapper
- Map Wrapper
- Collection Wrapper
- 自定义 Wrapper
Bean Wrapper
BeanWrapper中MetaClass是MyBatis类反射工具类,使用它可以非常方便的使用java反射而无须担心访问权限的问题.
BeanWrapper本质上就是根据字符串递归利用反射使用get,set来获取值和设置值.
Map Wrapper
逻辑与BeanWrapper基本一致
Collection Wrapper
这个类非常简单,因为它的绝大多数操作都会直接抛出异常
可是当我们使用tags[0]时是可以取值的,这是为什么?
因为在我们使用tags[0]时走的是MapWrapper和BeanWrapper共同父类BaseWrapper的逻辑而不是ColleactionWrapper
自定义 Wrapper
1 2 3 4 5 6 7
| class CustomObject{ public String name;
public CustomObject(String name){ this.name = name; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| class CustomObjectWrapper implements ObjectWrapper{
private CustomObject object;
public CustomObjectWrapper(CustomObject object){ this.object = object; }
@Override public Object get(PropertyTokenizer prop) { System.out.println("get");
if(prop.getName().equals("name")){ return this.object.name; } return null; }
@Override public void set(PropertyTokenizer prop, Object value) { System.out.println("set"); if(prop.getName().equals("name")){ this.object.name = (String) value; } }
@Override public String findProperty(String name, boolean useCamelCaseMapping) { System.out.println("findProperty"); return null; }
@Override public String[] getGetterNames() { System.out.println("getGetterNames"); return new String[0]; }
@Override public String[] getSetterNames() { System.out.println("getSetterNames"); return new String[0]; }
@Override public Class<?> getSetterType(String name) { System.out.println("getSetterType"); return null; }
@Override public Class<?> getGetterType(String name) { System.out.println("getGetterType"); return null; }
@Override public boolean hasSetter(String name) { System.out.println("hasSetter"); return false; }
@Override public boolean hasGetter(String name) { System.out.println("hasGetter"); return false; }
@Override public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) { System.out.println("instantiatePropertyValue"); return null; }
@Override public boolean isCollection() { System.out.println("isCollection"); return false; }
@Override public void add(Object element) { System.out.println("element"); }
@Override public <E> void addAll(List<E> element) { System.out.println("addAll"); } }
|
- 定义CustomObjectWrapperFactory
1 2 3 4 5 6 7 8 9 10 11 12
| class CustomObjectWrapperFactory implements ObjectWrapperFactory{
@Override public boolean hasWrapperFor(Object object) { return object instanceof CustomObject; }
@Override public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) { return new CustomObjectWrapper((CustomObject)object); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Test public void test() { CustomObject customObject = new CustomObject("名字"); CustomObjectWrapperFactory customObjectWrapperFactory = new CustomObjectWrapperFactory(); ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory(); DefaultReflectorFactory defaultReflectorFactory = new DefaultReflectorFactory(); MetaObject metaObject = MetaObject.forObject(customObject,DEFAULT_OBJECT_FACTORY,customObjectWrapperFactory,defaultReflectorFactory); Object name = metaObject.getValue("name"); System.out.println(name);
metaObject.setValue("name","名称1"); name = metaObject.getValue("name"); System.out.println(name); }
|