關於在MyBatis中的ObjectFactory有什麼用,在官方文檔中有這樣的描述(大多數網上的博客都是直接引用這一描述):MyBatis 每次建立結果對象的新實例時,它都會使用一個對象工廠(ObjectFactory)實例來完成。 默認的對象工廠須要作的僅僅是實例化目標類,要麼經過默認構造方法,要麼在參數映射存在的時候經過參數構造方法來實例化。 若是想覆蓋對象工廠的默認行爲,則能夠經過建立本身的對象工廠來實現。對於像我這種水平的來講,徹底就是一臉蒙逼,這到底有啥用?能夠說這個對象工廠就是用來建立實體類的,MyBatis有一個DefaultObjectFactory默認對象工廠類,就像上面所說的默認的對象工廠須要作的僅僅是實例化目標類,要麼經過默認構造方法,要麼在參數映射存在的時候經過參數構造方法來實例化。它不作其餘任何的處理。若是咱們想在建立實例化一個目標類的時候作點啥其餘的動做,能夠繼承DefaultObjectFactory,覆寫父類方法,並在mybatis-config.xml中註冊配置這個對象工廠類。html
本身實現一個對象工廠以下所示:java
1 package day_8_mybatis.util; 2 3 import java.util.Collection; 4 import java.util.Iterator; 5 import java.util.Properties; 6 7 import org.apache.ibatis.reflection.factory.DefaultObjectFactory; 8 9 import day_8_mybatis.pojo.People; 10 11 /** 12 * @author turbo 13 * 14 * 2016年10月24日 15 */ 16 public class ExampleObjectFactory extends DefaultObjectFactory { 17 18 @Override 19 public Object create(Class type) { 20 if (type.equals(People.class)){ 21 People p = (People)super.create(type); 22 p.setAge(22); 23 p.setName("keven"); 24 return p; 25 } 26 return super.create(type); 27 } 28 29 @Override 30 public void setProperties(Properties properties) { 31 Iterator iterator = properties.keySet().iterator(); 32 while (iterator.hasNext()){ 33 String keyValue = String.valueOf(iterator.next()); 34 System.out.println(properties.getProperty(keyValue)); 35 } 36 super.setProperties(properties); 37 } 38 39 @Override 40 public <T> boolean isCollection(Class<T> type) { 41 return Collection.class.isAssignableFrom(type); 42 } 43 44 }
咱們能夠先看下第30行這個setProperties方法,發現有一個Properties參數傳遞進來,這個參數在哪兒傳遞的呢?就是在咱們的mybatis-config.xml的第18行。mysql
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 6 <configuration> 7 <!-- 注意configuration中各個屬性配置的順序應爲:properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databaseIdProvider,mappers)--> 8 <properties> 9 <property name="driver" value="com.mysql.jdbc.Driver"/> 10 <property name="url" value="jdbc:mysql://localhost:3306/test"/> 11 <property name="username" value="root"/> 12 <property name="password" value="0000"/> 13 </properties> 14 <typeHandlers> 15 <typeHandler handler="day_8_mybatis.util.ExampleTypeHandler" javaType="java.util.Date" jdbcType="VARCHAR"/> 16 </typeHandlers> 17 <objectFactory type="day_8_mybatis.util.ExampleObjectFactory"> 18 <property name="someProperty" value="100"/> 19 </objectFactory> 20 <environments default="development"> 21 <environment id="development"> 22 <transactionManager type="JDBC" /> 23 <dataSource type="POOLED"> 24 <property name="driver" value="${driver}"/> 25 <property name="url" value="${url}"/> 26 <property name="username" value="${username}"/> 27 <property name="password" value="${password}"/> 28 </dataSource> 29 </environment> 30 </environments> 31 <mappers> 32 <mapper resource="day_8_mybatis/mapper/UserMapper.xml"/> 33 <mapper resource="day_8_mybatis/mapper/NoteMapper.xml"/> 34 </mappers> 35 36 </configuration> 37 38
選擇性忽略14-16行的typeHandlers配置,那是在上一節將typeHandlers用到的配置。sql
咱們就實現了這麼個自定義對象工廠,在客戶端代碼中測試一下。apache
1 package day_8_mybatis; 2 3 import java.io.IOException; 4 5 import org.apache.ibatis.session.SqlSession; 6 7 import day_8_mybatis.util.SessionFactory; 8 9 /** 10 * 客戶端 11 * @author turbo 12 * 13 * 2016年9月11日 14 */ 15 public class Main { 16 17 /** 18 * @param args 19 * @throws IOException 20 */ 21 public static void main(String[] args) throws Exception { 22 String resource = "day_8_mybatis/mybatis-config.xml"; //獲取mybatis配置文件路徑 23 SqlSession sqlSession = SessionFactory.getSqlSession(resource); //經過SessionFactory工具類(此工具類爲本身構造即util包中的SessionFactory)構造SqlSession 24 25 } 26 27 }
會發現控制檯會有一個100的輸出,那正是咱們傳遞進去的參數。但彷佛疑問在咱們好像並無調用任何方法啊,其實否則,mybatis的配置文件就是mybatis初始化首先要作的。咱們在第2二、23行作的工做就是加載configuration配置文件初始化mybatis,用於咱們配置了ObjectFactory中的property固然實際上也就調用了ExampleObjectFactory中的setProperties。不少不少框架作的第一件事就是加載配置文件,根據配置初始化各類類各類服務,固然這也能夠用代碼來實現,不過框架的好處就是它已經爲咱們作了一些事情,使得咱們僅僅須要經過一些配置就能實現咱們想要的結果。那麼至於create方法呢?咱們能夠上面說了對象工廠就是用來建立實例的,咱們能夠傳遞一個class類型的類,就能夠經過對象工廠的create方法獲得這個類的實例。session
1 package day_8_mybatis; 2 3 import java.io.IOException; 4 5 import org.apache.ibatis.session.SqlSession; 6 7 import day_8_mybatis.pojo.People; 8 import day_8_mybatis.util.ExampleObjectFactory; 9 import day_8_mybatis.util.SessionFactory; 10 11 /** 12 * 客戶端 13 * @author turbo 14 * 15 * 2016年9月11日 16 */ 17 public class Main { 18 19 /** 20 * @param args 21 * @throws IOException 22 */ 23 public static void main(String[] args) throws Exception { 24 String resource = "day_8_mybatis/mybatis-config.xml"; //獲取mybatis配置文件路徑 25 SqlSession sqlSession = SessionFactory.getSqlSession(resource); //經過SessionFactory工具類(此工具類爲本身構造即util包中的SessionFactory)構造SqlSession 26 ExampleObjectFactory e = new ExampleObjectFactory(); 27 People p = (People) e.create(People.class); 28 System.out.println(p.getName()); 29 } 30 31 }
最後記住上面提到的MyBatis初始化過程就是解析配置文件建立Configuration對象的過程。這也會爲咱們在瞭解MyBatis以後學習其源碼所要知道的一點。mybatis