Mybatis-ObjectFactory

来源:互联网 发布:正则匹配ip端口号 编辑:程序博客网 时间:2024/06/06 00:51

在Mybatis中ObjectFactory在很多时候也是必不可少的,那么接下来我们逐步了解一下。

首先看一下官方的文档,如下:

Each time MyBatis creates a new instance of a result object, it uses an ObjectFactory instance to

do so. The default ObjectFactory does little more than instantiate the target class with a default constructor,

or a parameterized constructor if parameter mappings exist. If you want to override the default behaviour of the ObjectFactory, you can create your own.

For example:

译:MyBatis 每次在创建结果对象的新实例时, 是使用 ObjectFactory (对象工厂)实例来完成的(补充:这里有两种方法,即使用默认构造方法进行实例化,或者在

参数映射存在的情况下,使用参数构造方法来完成对目标类的实例化)。

如果参数映射存在,默认的 ObjectFactory   所做的工作并没有带参构造方法所做的多。如果想要重写默认的 ObjectFactory,

可以创建自己的对象工厂来完成(即重写ObjectFactory方法)。如下:

// ExampleObjectFactory.javapublic class ExampleObjectFactory extends DefaultObjectFactory {public Object create(Class type) {return super.create(type);}public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) {return super.create(type, constructorArgTypes, constructorArgs);}public void setProperties(Properties properties) {super.setProperties(properties);}public <T> boolean isCollection(Class<T> type) {return Collection.class.isAssignableFrom(type);}}

<!-- mybatis-config.xml --><objectFactory type="org.mybatis.example.ExampleObjectFactory"><property name="someProperty" value="100"/></objectFactory>

The ObjectFactory interface is very simple. It contains two create methods, one to deal with the default constructor,

and the other to deal with parameterized constructors. Finally, the setProperties method can be used to configure the ObjectFactory.

Properties defined within the body of the objectFactory element will be passed to the setProperties method after initialization of your ObjectFactory instance.

译:ObjectFactory接口是很简单的。它包含了默认构造方法与带参构造方法两种实例化的方法。最后,使用setProperties方法来配置ObjectFactory,

在初始化ObjectFactory实例后,ObjectFactory元素体中定义的属性就会被传递给setProperties。


根据官方文档,显然是得不到很具体的用法,大概意思就是说这个对象工厂是用来实例化目标类的,那么实例化目标类分为两种方法,在默认情况下,我们是

不需要对其进行操作的,对象工厂会通过自带的默认构造方法进行相应的处理;但是在有需求的情况下,我们可以通过重写带参构造方法来达到需求,那么在

重写方法时,我们还可以通过配置文件传递properties的值。其实这在应用中还是很有用的,比如,我们在构造方法中可以做一些工作,在应用中,我们可能在

应用目标类实例化之前就需要做一些工作,那么我们就可以在这里进行重写。(个人观点)


那么接下来我们通过例子进行说明。

首先,重写ObjectFactory方法。如下:

package com.sw.obfa;import java.sql.Connection;import java.util.Iterator;import java.util.Properties;import org.apache.ibatis.reflection.factory.DefaultObjectFactory;/* *@Author swxctx *@time 2017年3月22日 *@Explain: */@SuppressWarnings("serial")public class ExampleObjectFactory extends DefaultObjectFactory{@SuppressWarnings({ "unchecked", "rawtypes" })@Overridepublic Object create(Class type) {// TODO Auto-generated method stub//带参,实例化目标类if(type.equals(User.class)){//实例化User类User user = (User)super.create(type);//值设置user.setId(1);user.setUsername("Swxctx");return user;}return super.create(type);}@Overridepublic void setProperties(Properties properties) {// TODO Auto-generated method stub@SuppressWarnings("rawtypes")Iterator iterator= properties.keySet().iterator();while(iterator.hasNext()){//迭代器 输出配置文件定义的数据String value = String.valueOf(iterator.next());System.out.println(properties.getProperty(value));}//传入propertysuper.setProperties(properties);}@Overridepublic <T> boolean isCollection(Class<T> type) {// TODO Auto-generated method stubreturn Connection.class.isAssignableFrom(type);}}
在上面代码中,已经进行注释,create方法即用来进行类实例化的,这里实例化的是user类,setProperties方法所做的工作即是传递properties数据(从配置文件中定义)
接下来编写配置文件:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 数据库属性配置文件 --><properties resource="db.properties"></properties><!-- 类型即为objectFactory路径 --><objectFactory type="com.sw.obfa.ExampleObjectFactory"><!-- 设置值 --><property name="someProperty" value="10"/><property name="someProperty2" value="11"/></objectFactory><!-- 配置数据库连接属性 --><environments default="development"><environment id="development"><!-- 使用jdbc事务管理 --><transactionManager type="JDBC"/><!-- 配置数据库连接池 --><dataSource type="POOLED"><!-- driver --><property name="driver" value="${jdbc.driver}"/><!-- url --><property name="url" value="${jdbc.url}"/><!-- user --><property name="username" value="${jdbc.username}"/><!-- password --><property name="password" value="${jdbc.password}"/></dataSource></environment></environments></configuration>
在上面的代码中,通过对ObjectFactory属性的设定,设置了两个值10、11
用到的po类(User):

package com.sw.obfa;/* *@Author swxctx *@time 2017年3月22日 *@Explain: */public class User {private int id;private String username;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}}

下面,我们通过测试代码进行测试:

package com.sw.obfa;import java.io.InputStream;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;/* *@Author swxctx *@time 2017年3月22日 *@Explain:测试类 */public class Test {private SqlSessionFactory sqlSessionFactory;@Beforepublic void setUp() throws Exception {//配置文件String resource = "SqlMapConfig.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}@org.junit.Testpublic void testValue() {@SuppressWarnings("unused")SqlSession sqlSession = sqlSessionFactory.openSession();}@org.junit.Testpublic void testCreate(){@SuppressWarnings("unused")SqlSession sqlSession = sqlSessionFactory.openSession();//实例化工厂类ExampleObjectFactory exampleObjectFactory = new ExampleObjectFactory();//通过工厂创建User类实例User user = (User) exampleObjectFactory.create(User.class);System.out.println(user.getId());System.out.println(user.getUsername());}}

首先,运行testValue方法,得到如下结果:

我们看到,运行后输出了在配置文件中配置的数据,这是为什么呢?显然,我们是没有调用任何方法进行任何操作的,但是在程序运行中,

首先进行的是配置文件的读取,进行mybatis的处置化工作,而数据被我们配置在了配置文件中,通过加载配置文件,配置文件就将数据传到了ObjectFactory的setProperties中,

那么在运行后,我们自然就可以看到运行后产生的输出结果。其实,基本所有的应用在启动时,首先都是读取的配置文件。

上面只是演示了对象工厂的执行,并没有演示其创建类的实例,对象工厂最主要的作用就是实例化目标类,那么接下来我们执行testCreate方法,

结果如下:

通过运行结果可以看到,User类已经被成功的创建了。

至此,对于ObjectFactory的讲解也基本告一段落了,其实对于ObjectFactory,了解其本质作用,以及Mybatis的执行过程,对ObjectFactory的了解

也基本差不多了,当然,在3.2.7中,还有一些其他的方法,可以在实例中去进一步的了解,但最主要的作用就是创建对象,实例化目标类。

0 0