MyBatis之ObjectFactory

關於在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

相關文章
相關標籤/搜索