MyBatis 核心配置说明(下)--objectWrapperFactory 元素
objectWrapperFactory 元素用于配置对象包装工厂(ObjectWrapperFactory),而 ObjectWrapperFactory 负责创建对象包装器(ObjectWrapper),ObjectWrapper 负责将 SQL 查询的结果集与 Java 对象的字段进行映射,它在 DTD 中的定义如下:
<!ELEMENT objectWrapperFactory EMPTY>
<!ATTLIST objectWrapperFactory
type CDATA #REQUIRED
>
objectWrapperFactory 元素只有一个子元素 objectWrapperFactory,用于配置 ObjectWrapperFactory 的实现,例如:
<configuration>
<objectWrapperFactory type="com.wyz.customize.factory.wrapper.CustomizeObjectWrapperFactory"/>
</configuration>
可以看到,这里我配置的是 CustomizeObjectWrapperFactory,即自定义的 ObjectWrapper 工厂,那么下面我们就实现这个 CustomizeObjectWrapperFactory。
首先我们要先实现对象包装器,在 MyBatis 中只需要继承 ObjectWrapper 接口即可,这里我们偷个懒,直接继承 ObjectWrapper 的实现类 BeanWrapper,代码如下:
package com.wyz.customize.wrapper.object;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.reflection.wrapper.BeanWrapper;
public class CustomizeObjectWrapper extends BeanWrapper {
public CustomizeObjectWrapper(MetaObject metaObject, Object object) {
super(metaObject, object);
}
@Override
public void set(PropertyTokenizer prop, Object value) {
super.set(prop, value);
}
@Override
public String findProperty(String name, boolean useCamelCaseMapping) {
return super.findProperty(name, useCamelCaseMapping);
}
@Override
public Class<?> getSetterType(String name) {
return super.getSetterType(name);
}
@Override
public boolean hasSetter(String name) {
return super.hasSetter(name);
}
@Override
public boolean hasGetter(String name) {
return super.hasGetter(name);
}
}
这里我只保留了几个关键方法:
-
BeanWrapper#set
,用于将查询到的数据库结果集中字段的值赋值到 Java 对象的实例的指定属性上; -
BeanWrapper#findProperty
,用于获取数据库表中字段在 Java 对象中的映射,例如:数据库表中的 user_id 映射到 Java 对象中的 userId; -
BeanWrapper#getSetterType
,用于获取 Java 对象中字段的类型; -
BeanWrapper#hasSetter
和BeanWrapper#hasGetter
,用于判断 Java 对象中的属性是否有 getter 方法和 setter 方法。
接着我们来实现对象包装器工厂,同样的 MyBatis 中也提供了 ObjectWrapperFactory 接口,我这里同样选择继承 ObjectWrapperFactory 接口的实现类 DefaultObjectWrapperFactory,代码如下:
package com.wyz.customize.factory.wrapper;
import com.wyz.customize.wrapper.object.CustomizeObjectWrapper;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
public class CustomizeObjectWrapperFactory extends DefaultObjectWrapperFactory {
public CustomizeObjectWrapperFactory() {
super();
}
@Override
public boolean hasWrapperFor(Object object) {
return true;
}
@Override
public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
return new CustomizeObjectWrapper(metaObject, object);
}
}
ObjectWrapperFactory 接口的核心方法是ObjectWrapperFactory#getWrapperFor
,用于从对象包装器工厂中返回对象包装器,因此该方法中我没有直接调用父类的视线,而是返回我们自定义对象包装器 CustomizeObjectWrapper 的实例。
在上一篇MyBatis 核心配置讲解(上)中我们已经知道,ObjectFactory 是用于创建 SQL 语句的结果集映射到的 Java 对象的实例,那么 ObjectWrapper 就是用于为已经创建的 Java 对象实例中的每个字段进行赋值的。
同样的,MyBatis 中提供的 ObjectWrapper 也已经满足了绝大部分场景,因此通常来说,我们也不太需要自定义 ObjectWrapper。