美文网首页
Mybatis系列之二 Mapper对象获取

Mybatis系列之二 Mapper对象获取

作者: 超人也害羞 | 来源:发表于2019-07-13 21:45 被阅读0次

    一、思路

    1. Mybatis Mapper对象获取过程分析;
    2. MapperProxy怎么执行sql
    3. SqlSession的生命周期?
    4. SqlSession如何和Mapper对象绑定?
    5. Spring怎么管理mybatis的事务呢?

    二、Mybatis Mapper对象获取过程分析;

    重点关注mybatis和spring结合后是怎么获取mapper对象;根据下面的BPMN图来看源码;


    MapperProxy获取过程.jpg

    a.
    关注MapperFactoryBean这个类,

      @Override
      public T getObject() throws Exception {
        return getSqlSession().getMapper(this.mapperInterface);
      }
    

    SqlSessionTemplate

    @Override
      public <T> T getMapper(Class<T> type) {
        return getConfiguration().getMapper(type, this);
      }
    

    Configuration

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

    MapperRegistry

    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);
        }
      }
    

    MapperProxyFactory

    @SuppressWarnings("unchecked")
      protected T newInstance(MapperProxy<T> mapperProxy) {
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
      }
    
      public T newInstance(SqlSession sqlSession) {
        final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
        return newInstance(mapperProxy);
      }
    

    三、MapperProxy怎么执行sql

    public class MapperProxy<T> implements InvocationHandler, Serializable {
    
      private static final long serialVersionUID = -6424540398559729838L;
      private final SqlSession sqlSession;
      private final Class<T> mapperInterface;
      private final Map<Method, MapperMethod> methodCache;
    
      // ... 省略部分内容
    
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())) {
          try {
            return method.invoke(this, args);
          } catch (Throwable t) {
            throw ExceptionUtil.unwrapThrowable(t);
          }
        }
    
        // 执行真正的sql方法
        final MapperMethod mapperMethod = cachedMapperMethod(method);
        return mapperMethod.execute(sqlSession, args);
      }
    
      private MapperMethod cachedMapperMethod(Method method) {
        MapperMethod mapperMethod = methodCache.get(method);
        if (mapperMethod == null) {
          mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
          methodCache.put(method, mapperMethod);
        }
        return mapperMethod;
      }
    
    }
    

    未完待续 ...

    相关文章

      网友评论

          本文标题:Mybatis系列之二 Mapper对象获取

          本文链接:https://www.haomeiwen.com/subject/atfmkctx.html