MetaObject类相当于一个对象工具类,Mybatis在sql参数设置和结果集映射里经常使用到这个对象。
映射是指结果集中的列填充至JAVA Bean属性。这就必须用到反射,而Bean的属性 多种多样的有普通属性、对象、集合、Map都有可能。为了更加方便的操作Bean的属性,MyBatis提供了MeataObject 工具类,其简化了对象属性的操作。
/**
* 对象元数据,提供了对象的属性值的获得和设置
*
* @author Clinton Begin
*/
public class MetaObject {
/**
* 原始 Object 对象
*/
private final Object originalObject;
/**
* 封装过的 Object 对象
*/
private final ObjectWrapper objectWrapper;
private final ObjectFactory objectFactory;
private final ObjectWrapperFactory objectWrapperFactory;
private final ReflectorFactory reflectorFactory;
private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
this.originalObject = object;
this.objectFactory = objectFactory;
this.objectWrapperFactory = objectWrapperFactory;
this.reflectorFactory = reflectorFactory;
if (object instanceof ObjectWrapper) {
this.objectWrapper = (ObjectWrapper) object;
} else if (objectWrapperFactory.hasWrapperFor(object)) {
// 创建 ObjectWrapper 对象
this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
} else if (object instanceof Map) {
// 创建 MapWrapper 对象
this.objectWrapper = new MapWrapper(this, (Map) object);
} else if (object instanceof Collection) {
// 创建 CollectionWrapper 对象
this.objectWrapper = new CollectionWrapper(this, (Collection) object);
} else {
// 创建 BeanWrapper 对象
this.objectWrapper = new BeanWrapper(this, object);
}
}
/**
* 创建 MetaObject 对象
*
* @param object 原始 Object 对象
* @param objectFactory
* @param objectWrapperFactory
* @param reflectorFactory
* @return MetaObject 对象
*/
public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
if (object == null) {
return SystemMetaObject.NULL_META_OBJECT;
} else {
return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}
}
public ObjectFactory getObjectFactory() {
return objectFactory;
}
public ObjectWrapperFactory getObjectWrapperFactory() {
return objectWrapperFactory;
}
public ReflectorFactory getReflectorFactory() {
return reflectorFactory;
}
public Object getOriginalObject() {
return originalObject;
}
/**
* 1.查找对象中的属性,可以下划线转驼峰查找
* @param propName
* @param useCamelCaseMapping 下划线转驼峰查找
* @return
*/
public String findProperty(String propName, boolean useCamelCaseMapping) {
return objectWrapper.findProperty(propName, useCamelCaseMapping);
}
/**
* 获取get方法属性名称和get方法去掉get后边的属性名称
* getIds(){return id;} --> (id、ids)
* @return
*/
public String[] getGetterNames() {
return objectWrapper.getGetterNames();
}
/**
* 获取set方法属性名称和set方法去掉set后边的属性名称
* setIds(){return id;} --> (id、ids)
* @return
*/
public String[] getSetterNames() {
return objectWrapper.getSetterNames();
}
/**
* 获取set方法后边属性的类型
* @param name 这个name 要和setXXX方法中的XXX相同才能获取到,否则抛异常
* @return
*/
public Class<?> getSetterType(String name) {
return objectWrapper.getSetterType(name);
}
/**
* 获取get方法后边属性的类型
* @param name 这个name,要个getXXX方法中的XXX相同才能获取到,否则抛异常
* @return
*/
public Class<?> getGetterType(String name) {
return objectWrapper.getGetterType(name);
}
/**
* 判断name是否是setXXX()方法中的XXX
* @param name
* @return
*/
public boolean hasSetter(String name) {
return objectWrapper.hasSetter(name);
}
/**
* 判断name是否是getXXX()方法中的XXX
* @param name
* @return
*/
public boolean hasGetter(String name) {
return objectWrapper.hasGetter(name);
}
/**
* 获取对象属性值,可以递归获取
* @param name
* @return
*/
public Object getValue(String name) {
// 创建 PropertyTokenizer 对象,对 name 分词
PropertyTokenizer prop = new PropertyTokenizer(name);
// 有子表达式
if (prop.hasNext()) {
// 创建 MetaObject 对象
MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
// 递归判断子表达式 children ,获取值,metaValue == null,则返回null
if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
return null;
} else {
return metaValue.getValue(prop.getChildren());
}
// 无子表达式
} else {
// 获取值
return objectWrapper.get(prop);
}
}
/**
* 给对象属性设置值,可以递归设置,基本类型,数组,对象,都可以自动创建
* 但是ArrayList和数组需要手动创建
* List必须创建对象,添加进list
* @param name
* @param value
*/
public void setValue(String name, Object value) {
// 创建 PropertyTokenizer 对象,对 name 分词
PropertyTokenizer prop = new PropertyTokenizer(name);
// 有子表达式
if (prop.hasNext()) {
// 创建 MetaObject 对象
MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
// 递归判断子表达式 children ,设置值
if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
if (value == null) {
// don't instantiate child path if value is null
return;
} else {
// 创建值
metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
}
}
// 设置值
metaValue.setValue(prop.getChildren(), value);
// 无子表达式
} else {
// 设置值
objectWrapper.set(prop, value);
}
}
public MetaObject metaObjectForProperty(String name) {
// 获得属性值
Object value = getValue(name);
// 创建 MetaObject 对象
return MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory);
}
public ObjectWrapper getObjectWrapper() {
return objectWrapper;
}
public boolean isCollection() {
return objectWrapper.isCollection();
}
/**
* 不支持add操作
* @param element
*/
public void add(Object element) {
objectWrapper.add(element);
}
/**
* 不支持addAll操作
* @param list
* @param <E>
*/
public <E> void addAll(List<E> list) {
objectWrapper.addAll(list);
}
}
public class MetaObjectTest {
@Test
public void test(){
Role role = new Role();
MetaObject metaObject = SystemMetaObject.forObject(role);
//设置基本类型
metaObject.setValue("name", "管理员");
metaObject.setValue("role_id", 1);
//设置List<Object>
List<Permission> permissions = new ArrayList<>();
Permission permission = new Permission();
permissions.add(permission);
metaObject.setValue("permissions", permissions);
metaObject.setValue("permissions[0].name", "查看列表权限");
//设置对象Object
metaObject.setValue("user.name", "张三");
//设置数组Array
String[] arr = new String[2];
metaObject.setValue("pers", arr);
metaObject.setValue("pers[0]", "111");
//设置List<Integer>
List<Integer> ages = new ArrayList<>();
ages.add(null);
metaObject.setValue("ages", ages);
metaObject.setValue("ages[0]", 2);
//设置Map
HashMap<String, String> map = new HashMap<>();
metaObject.setValue("map", map);
metaObject.setValue("map.key", "value");
metaObject.setValue("map.name", "lisi");
System.out.println(role);
}
}
public class Role {
private Integer role_id;
private String name;
private List<Permission> permissions;
private User user;
private Integer userId;
private String[] pers;
private List<Integer> ages;
private Map<String, String> map;
}
public class Permission {
private Integer id;
private String name;
}