当创建结果集时,MyBatis 会使用一个对象工厂来完成创建这个结果集实例。在默认的情况下,MyBatis 会使用其定义的对象工厂——DefaultObjectFactory(org.apache.ibatis.reflection.factory.DefaultObjectFactory)来完成对应的工作。

    MyBatis 允许注册自定义的 ObjectFactory。如果自定义,则需要实现接口 org.apache.ibatis.reflection.factory.ObjectFactory,并给予配置。

    在大部分的情况下,我们都不需要自定义返回规则,因为这些比较复杂而且容易出错,在更多的情况下,都会考虑继承系统已经实现好的 DefaultObjectFactory ,通过一定的改写来完成我们所需要的工作,如下所示。

    1. package com.mybatis.test;

    2. import java.util.List;
    3. import java.util.Properties;

    4. import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
    5. import org.apache.log4j.Logger;

    6. public class MyObjectFactory extends DefaultObjectFactory {

    7. private static final long serialVersionUID = -4293520460481008255L;

    8. Logger log = Logger.getLogger(MyObjectFactory.class);

    9. private Object temp = null;

    10. @Override
    11. public void setProperties(Properties properties) {
    12. super.setProperties(properties);
    13. log.info(“初始化参数:【” + properties.toString() + “】”);
    14. }

    15. // 方法2
    16. @Override
    17. public T create(Class type) {
    18. T result = super.create(type);
    19. log.info(“创建对象:” + result.toString());
    20. log.info(“是否和上次创建的是同一个对象:【” + (temp == result) + “】”);
    21. return result;
    22. }

    23. // 方法1
    24. @Override
    25. public T create(Class type, List> constructorArgTypes,
    26. List constructorArgs) {
    27. T result = super.create(type, constructorArgTypes, constructorArgs);
    28. log.info(“创建对象:” + result.toString());
    29. temp = result;
    30. return result;
    31. }

    32. @Override
    33. public boolean isCollection(Class type) {
    34. return super.isCollection(type);
    35. }
    36. }
    37. 然后对它进行配置,如下所示。



      这样 MyBatis 就会采用配置的 MyObjectFactory 来生成结果集对象,采用下面的代码进行测试。

      1. package com.mybatis.test;

      2. import java.io.IOException;
      3. import java.io.InputStream;

      4. import org.apache.ibatis.io.Resources;
      5. import org.apache.ibatis.session.SqlSession;
      6. import org.apache.ibatis.session.SqlSessionFactory;
      7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
      8. import org.apache.log4j.Logger;

      9. import com.mybatis.mapper.UserMapper;
      10. import com.mybatis.po.User;

      11. public class MyBatisTest {
      12. public static void main(String[] args) throws IOException {
      13. Logger log = Logger.getLogger(MyBatisTest.class);
      14. InputStream config = Resources
      15. .getResourceAsStream(“mybatis-config.xml”);
      16. SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
      17. SqlSession ss = ssf.openSession();
      18. UserMapper userMapper = ss.getMapper(UserMapper.class);
      19. User user = userMapper.getUser(1L);
      20. System.out.println(user.getUserName());
      21. }
      22. }

      当配置了 log4j.properties 文件的时候,就能看到下图中的输出日志。

      19-MyBatis ObjectFactory(对象工厂) - 图1

      如果打断点调试一步步跟进,那么你会发现 MyBatis 创建了一个 List 对象和一个 User 对象。它会先调用方法 1,然后调用方法 2,只是最后生成了同一个对象,所以在写入的判断中,始终返回的是 true。因为返回的是一个 User 对象,所以它会最后适配为一个 User 对象,这就是它的工作过程。