八、SqlSession 执行 Mapper 过程详解

  • 源码地址:https://github.com/RononoaZoro/mybatis-book/tree/master 的 mybatis-book ( mybatis-chapter06 )
  • 文章内容出自《Mybatis 3 源码深度解析》第六章
  • 自己实现代码地址:https://github.com/RononoaZoro/mybatis-book/tree/master 的 archer-mybatis
package com.blog4java.mybatis.example;

import com.alibaba.fastjson.JSON;
import com.blog4java.common.DbUtils;
import com.blog4java.mybatis.example.entity.UserEntity;
import com.blog4java.mybatis.example.mapper.UserMapper;
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.apache.ibatis.session.SqlSessionManager;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.List;

public class MybatisExample {
   

    @Before
    public void initData() {
   
        DbUtils.initData();
    }

    @Test
    public  void testMybatis () throws IOException {
   
        // 获取配置文件输入流
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        // 通过SqlSessionFactoryBuilder的build()方法创建SqlSessionFactory实例
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 调用openSession()方法创建SqlSession实例
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 获取UserMapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 执行Mapper方法,获取执行结果
        List<UserEntity> userList = userMapper.listAllUser();
         /*
        // 兼容Ibatis,通过Mapper Id执行SQL操作
        List<UserEntity> userList = sqlSession.selectList(
                "com.blog4java.mybatis.com.blog4java.mybatis.example.mapper.UserMapper.listAllUser");
        */
        System.out.println(JSON.toJSONString(userList));
    }
}

1、核心配置类 Configuration 初始化

2、创建 SqlSession 对象

3、获取 UserMapper 的动态代理对象

在这里插入图片描述

// 获取UserMapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

SqlSession.java 部分代码

public class SqlSession {
   
      /**
   * Retrieves a mapper.
   * @param <T> the mapper type
   * @param type Mapper interface class
   * @return a mapper bound to this SqlSession
   */
  <T> T getMapper(Class<T> type);
}

DefaultSqlSession.java 部分代码

/**
 *
 * The default implementation for {@link SqlSession}.
 * Note that this class is not Thread-Safe.
 *
 * @author Clinton Begin
 */
public class DefaultSqlSession implements SqlSession {
   

  private final Configuration configuration;
  private final Executor executor;

  private final boolean autoCommit;
  private boolean dirty;
  private List<Cursor<?>> cursorList;

  public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
   
    this.configuration = configuration;
    this.executor = executor;
    this.dirty = false;
    this.autoCommit = autoCommit;
  }

  public DefaultSqlSession(Configuration configuration, Executor executor) {
   
    this(configuration, executor, false);
  }  
    
    
  @Override
  public <T> T getMapper(Class<T> type) {
   
    return configuration.<T>getMapper(type, this);
  }
}

Configuration.java 部分代码

public class Configuration {
     
    protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
    
      public void addMappers(String packageName, Class<?> superType) {
   
        mapperRegistry.addMappers(packageName, superType);
      }

      public void addMappers(String packageName) {
   
        mapperRegistry.addMappers(packageName);
      }

      public <T> void addMapper(Class<T> type) {
   
        mapperRegistry.addMapper(type);
      }
    
      public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
   
        return mapperRegistry.getMapper(type, sqlSession);
      }
}

MapperRegistry.java 部分代码

  • Configuration 初始化会填充 MapperRegistry 对象
public class MapperRegistry {
   
  // Configuration对象引用
  private final Configuration config;
  // 用于注册Mapper接口Class对象,和MapperProxyFactory对象对应关系
  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();

  public MapperRegistry(Configuration config) {
   
    this.config = config;
  }
  // 根据Mapper接口Class对象获取Mapper动态代理对象
  @SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
   
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    if (mapperProxyFactory == null) {
   
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {
   
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
   
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }

  // 根据Mapper接口Class对象,创建MapperProxyFactory对象,并注册到knownMappers属性中
  public <T> void addMapper(Class<T> type) {
   
    if (type.isInterface()) {
   
      if (hasMapper(type)) {
   
        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
      }
      boolean loadCompleted = false;
      try {
   
        knownMappers.put(type, new MapperProxyFactory<T>(type));
        // It's important that the type is added before the parser is run
        // otherwise the binding may automatically be attempted by the
        // mapper parser. If the type is already known, it won't try.
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
      } finally {
   
        if (!loadCompleted) {
   
          knownMappers.remove(type);
        }
      }
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值