欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

MyBatis 核心配置说明(下)--objectWrapperFactory 元素

最编程 2024-05-05 21:38:59
...

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#hasSetterBeanWrapper#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。