博由
objectFactory对象工厂,在mybatis的对象创建是通过objectFactory完成的。缺省的实现是DefaultObjectFactory,如果想实现自己的ObjectFactory可以实现ObjectFactory或者继承DefaultObjectFactory。
ObjectFactory 使用解析
默认配置
Configuration.java
protected ObjectFactory objectFactory = new DefaultObjectFactory();
XmlConfigBuilder.java
private void objectFactoryElement(XNode context) throws Exception {
if (context != null) {
// 如果objectFactory设置,那么覆盖DefaultObjectFactory
String type = context.getStringAttribute("type");
Properties properties = context.getChildrenAsProperties();
ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
factory.setProperties(properties);
configuration.setObjectFactory(factory);
}
}
DefaultObjectFactory.java
1. create: 创建对象
2. setProperties: 设置属性
3. isCollection: 是否是集合对象
DefaultObjectFactory提供了基本的创建对象的方法和解析方式。
对象创建使用情况
DefaultResultSetHandler 类中频繁的使用了DefaultObjectFactory相关方法,用于创建对象。
例如:
DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
基本使用了objectFactory.create(type);
案例
1. 创建自定义ObjectFactory
package com.objectfactory.factorys;
import com.objectfactory.pojo.User;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import java.util.*;
/**
* 一般通过继承DefaultObjectFactory来自定义ObjectFactory
* Created by wangzhiping on 17/3/12.
*/
public class TestObjectFactory extends DefaultObjectFactory {
/**
* 设置属性
* @param properties
*/
@Override
public void setProperties(Properties properties) {
Set<Object> keys = properties.keySet();
for(Iterator<Object> i = keys.iterator(); i.hasNext();) {
System.out.println(" ====== " + properties.get(i.next()) + " ====== ");
}
super.setProperties(properties);
}
/**
* 创建对象
* @param type
* @return
*/
@Override
public Object create(Class type) {
if (type.equals(User.class)){
User user = (User)super.create(type);
user.setName("---create---");
user.setCreatedAt(new Date());
return user;
}
return super.create(type);
}
/**
* 创建对象根据指定的参数对象
* @param type
* @param constructorArgTypes
* @param constructorArgs
* @param <T>
* @return
*/
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return super.create(type, constructorArgTypes, constructorArgs);
}
/**
* 判断是否是集合
* @param type
* @param <T>
* @return
*/
@Override
public <T> boolean isCollection(Class<T> type) {
return super.isCollection(type);
}
}
2. 配置objectFactory
<objectFactory type="com.objectfactory.factorys.TestObjectFactory" >
<property name="username" value="wangzhiping" />
<property name="password" value="wangzhiping" />
</objectFactory>
3. 单元测试
@Test
public void testObjectFactory() {
SqlSession session = instance.getSession();
User user = session.selectOne(User.class.getName() + ".findById", 5);
System.out.println(user);
}
4. 测试结果
====== wangzhiping ======
====== wangzhiping ======
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1073533248.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3ffcd140]
==> Preparing: SELECT * FROM user WHERE id = ?
==> Parameters: 5(Integer)
<== Columns: id, name, created_at, updated_at
<== Row: 5, admin, 2017-02-20 02:32:37, 2017-02-20 02:32:37
<== Total: 1
User{id=5, name='admin', createdAt=Sun Mar 12 16:57:45 CST 2017, updatedAt=null}
-----------------------------------------------------
1. 属性来源于<objectFactory>中的<property>标签设置;
2. User->created_at属性,是通过create创建对象时,赋值结果;
总结
个人认为一般很少会使用到自定义ObjectFactory,如果需要使用的话,建议是在对象创建时需要做一些操作,或前或后,用于改变或者丰富被创建对象。
项目地址:
branch v1.5: https://github.com/wzpthq/csdn_mybatis.git