zoukankan      html  css  js  c++  java
  • MyBatis之ObjectFactory

    关于在MyBatis中的ObjectFactory有什么用,在官方文档中有这样的描述(大多数网上的博客都是直接引用这一描述):MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。对于像我这种水平的来说,完全就是一脸蒙逼,这到底有啥用?可以说这个对象工厂就是用来创建实体类的,MyBatis有一个DefaultObjectFactory默认对象工厂类,就像上面所说的默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。它不做其他任何的处理。如果我们想在创建实例化一个目标类的时候做点啥其他的动作,可以继承DefaultObjectFactory,覆写父类方法,并在mybatis-config.xml中注册配置这个对象工厂类。

    自己实现一个对象工厂如下所示:

     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行。

     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用到的配置。

    我们就实现了这么个自定义对象工厂,在客户端代码中测试一下。

     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初始化首先要做的。我们在第22、23行做的工作就是加载configuration配置文件初始化mybatis,用于我们配置了ObjectFactory中的property当然实际上也就调用了ExampleObjectFactory中的setProperties。很多很多框架做的第一件事就是加载配置文件,根据配置初始化各种类各种服务,当然这也可以用代码来实现,不过框架的好处就是它已经为我们做了一些事情,使得我们仅仅需要通过一些配置就能实现我们想要的结果。那么至于create方法呢?我们可以上面说了对象工厂就是用来创建实例的,我们可以传递一个class类型的类,就可以通过对象工厂的create方法得到这个类的实例。

     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之后学习其源码所要知道的一点。

  • 相关阅读:
    CSS实现雨滴动画效果
    大型网站架构系列:电商网站架构案例
    CSS 不定宽高的垂直水平居中方式总汇
    js中尺寸类样式
    Tiling
    排序二叉树
    算术表达式的转换
    Area
    catch that cow
    R中双表操作学习[转载]
  • 原文地址:https://www.cnblogs.com/yulinfeng/p/5995200.html
Copyright © 2011-2022 走看看