java metaobject_Mybatis3源码分析(12)-Sql解析执行-MetaObject

MetaObject是Mybatis中的一个关键工具类,用于便捷地设置SQL参数和映射结果。它封装了原始对象,并提供了getter、setter方法,支持对Map、Collection和普通Java对象的属性访问,包括复杂属性路径。MetaObject的实现通过不同的ObjectWrapper(如MapWrapper、BeanWrapper)处理不同类型的数据。通过对MetaObject的使用,可以实现类似于OGNL或JSTL的表达式访问方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MetaObject

MetaObject类相当于一个工具类,Mybatis在sql参数设置和结果集映射里经常使用到这个对象。下面来详细分析一下这类。

这个类有四个属性,其中两个基本不用看。

//原始的对象

private Object originalObject;

//对原始对象的一个包装

private ObjectWrapper objectWrapper;

//这两个属性基本不用,因为在Mybatis中都找不到ObjectWrapperFactory的有效实现类

private ObjectFactory objectFactory;

private ObjectWrapperFactory objectWrapperFactory;

再看他的方法

//构造方法

private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) {

this.originalObject = object;

this.objectFactory = objectFactory;

this.objectWrapperFactory = objectWrapperFactory;

if (object instanceof ObjectWrapper) {

this.objectWrapper = (ObjectWrapper) object;

} else if (objectWrapperFactory.hasWrapperFor(object)) {

this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);

} else if (object instanceof Map) {

this.objectWrapper = new MapWrapper(this, (Map) object);

} else if (object instanceof Collection) {

this.objectWrapper = new CollectionWrapper(this, (Collection) object);

} else {

this.objectWrapper = new BeanWrapper(this, object);

}

}

public String findProperty(String propName, boolean useCamelCaseMapping) {

return objectWrapper.findProperty(propName, useCamelCaseMapping);

}

public String[] getGetterNames() {

return objectWrapper.getGetterNames();

}

public String[] getSetterNames() {

return objectWrapper.getSetterNames();

}

public Class> getSetterType(String name) {

return objectWrapper.getSetterType(name);

}

public Class> getGetterType(String name) {

return objectWrapper.getGetterType(name);

}

public boolean hasSetter(String name) {

return objectWrapper.hasSetter(name);

}

public boolean hasGetter(String name) {

return objectWrapper.hasGetter(name);

}

//从originalObject获取属性值

public Object getValue(String name) {

PropertyTokenizer prop = new PropertyTokenizer(name);

if (prop.hasNext()) {

MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());

if (metaValue == SystemMetaObject.NULL_META_OBJECT) {

return null;

} else {

return metaValue.getValue(prop.getChildren());

}

} else {

return objectWrapper.get(prop);

}

}

//设置originalObject属性值

public void setValue(String name, Object value) {

PropertyTokenizer prop = new PropertyTokenizer(name);

if (prop.hasNext()) {

MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());

if (metaValue == SystemMetaObject.NULL_META_OBJECT) {

if (value == null && prop.getChildren() != null) {

return; // don't instantiate child path if value is null

} else {

metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);

}

}

metaValue.setValue(prop.getChildren(), value);

} else {

objectWrapper.set(prop, value);

}

}

//应该是对collection的操作

public void add(Object element) {

objectWrapper.add(element);

}

//应该是对collection的操作

public void addAll(List list) {

objectWrapper.addAll(list);

}

从上面代码中可以看出MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值。其中originalObject最主要的有三种类型:

Map类型

Collection类型

普通的java对象,有get和set方法的对象

getValue和setValue中的name参数支持复杂的属性访问:例如user.cust.custId,user.acts[0].acctId!

public Object getValue(String name) {

PropertyTokenizer prop = new PropertyTokenizer(name);

if (prop.hasNext()) {

MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());

if (metaValue == SystemMetaObject.NULL_META_OBJECT) {

return null;

} else {

//这里相当于递归调用,直到最后一层。例如user.cust.custId

//第一次递归cust.custId

//第二次递归custId,这个就是真正访问要返回的

return metaValue.getValue(prop.getChildren());

}

} else {

return objectWrapper.get(prop);

}

}

getValue,setValue,add,addAll方法都是委托objectWrapper对象实现的。下面详细分析objectWrapper对象。

MapWrapper

public Object get(PropertyTokenizer prop) {

if (prop.getIndex() != null) {//accts[0]这种方式

Object collection = resolveCollection(prop, map);

return getCollectionValue(prop, collection);

} else {//userId这种方式

return map.get(prop.getName());

}

}

public void set(PropertyTokenizer prop, Object value) {

if (prop.getIndex() != null) {//accts[0]这种方式

Object collection = resolveCollection(prop, map);

setCollectionValue(prop, collection, value);

} else {//userId这种方式

map.put(prop.getName(), value);

}

}

集合类的不支持

public void add(Object element) {

throw new UnsupportedOperationException();

}

public void addAll(List element) {

throw new UnsupportedOperationException();

}

CollectionWrapper

最支持如下两个方法,其他不支持

public void add(Object element) {

object.add(element);

}

public void addAll(List element) {

object.addAll(element);

}

BeanWrapper

public Object get(PropertyTokenizer prop) {

if (prop.getIndex() != null) {//accts[0]方式

Object collection = resolveCollection(prop, object);

return getCollectionValue(prop, collection);

} else {//userId方式,反射

return getBeanProperty(prop, object);

}

}

public void set(PropertyTokenizer prop, Object value) {

if (prop.getIndex() != null) {//accts[0]方式

Object collection = resolveCollection(prop, object);

setCollectionValue(prop, collection, value);

} else {//userId方法,反射

setBeanProperty(prop, object, value);

}

}

集合类的不支持

public void add(Object element) {

throw new UnsupportedOperationException();

}

public void addAll(List list) {

throw new UnsupportedOperationException();

}

小结

MetaObject是一个工具类,提供了类似ognl和jstl这样的方式去访问map,collection及javabean。

这里举三个例子来总结MetaObject最主要的功能

对Map操作

Map map=new HashMap<>();

MetaObject metaObject=MetaObject.forObject(map, objectFactory, objectWrapperFactory);

metaObject.setValue("UESR_ID", "123412");

//相当于执行了map.put("USER_ID","123412");

Object obj=metaObject.getValue("UESR_ID");

//相当于执行了map.get("UESR_ID");

对JavaBean操作

User user=new User();

MetaObject metaObject=MetaObject.forObject(user, objectFactory, objectWrapperFactory);

metaObject.setValue("userId", "123412");

//相当于执行了user.setUserId("123412");

Object obj=metaObject.getValue("userId");

//相当于执行了user.getUserId

对Collection操作

List list=new ArrayList<>();

MetaObject metaObject=MetaObject.forObject(list, objectFactory, objectWrapperFactory);

metaObject.add("ashan");

//相当于执行了list.add("ashan");

metaObject.getValue("[0]");

//相当于执行了list.get(0);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值