Mybatis獲取代理對象


  • mybatis-config.xml里 標簽可以放置多個environment,這里可以切換test和develop數據源
  • databaseIdProvider提供多種數據庫,在xml映射文件里選擇databaseId即可使用對應的數據庫
  • Oracle的自增是使用Sequence實現的,若要獲取插入數據的主鍵,在xml映射里寫上selectKey標簽,select seq.nextval from dual;
  • 哪些地方不能使用占位符?比如分表時表名,orderby,desc
  • @Mapkey("id")指定返回類型為map時,將id作為key

1. mybatis參數綁定的過程

我們寫一個UserMapper接口,Mybatis會為改接口創建一個MapperProxy對象。

1.1 MapperRegistry

在繼續之前,先來了解一下MapperRegistry。

  1. MapperRegistry是mapper的注冊類,提供了注冊一個包下面的所有Mapper接口。內部維護了一個 private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();map以mapper接口類為key,value是接口類對應的代理工廠。
    void addMapper(Class<T> type)方法簡單的將type放進knownMappers里面。不過,這里面還有
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();

這樣一個解析操作,暫不做分析。
2. <T> T getMapper(Class<T> type, SqlSession sqlSession)該方法是本類最重要的一個方法了,獲取Mapper接口的代理對象也正是從該方法獲取的。
該方法實現就是,knownMappers.get(type)得到代理對象工廠mapperProxyFactory,返回的是mapperProxyFactory.newInstance(sqlSession)
進入該方法發現過程也比較簡單,構造了一個MapperProxy對象

   public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

再進去看

  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

發現這就是標准的JDK面向接口的動態代理啊。要問對應的InvocationHandler在哪里?mapperProxy就是啦。
至此,Mybatis如何獲取Mapper接口的代理對象已經解決。
再梳理一下整個流程:

sqlsession.getMapper->configuration.getMapper->mapperRegistry.getMapper->獲取Mapper代理對象

1.2

創建好MapperProxy對象之后,調用Mapper.xx方法時就會走MapperProxy的invoke方法

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {//如果方法是在Object里面的,放行
        return method.invoke(this, args);
      } else if (isDefaultMethod(method)) {
        return invokeDefaultMethod(proxy, method, args);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
    final MapperMethod mapperMethod = cachedMapperMethod(method);//緩存method方法
    return mapperMethod.execute(sqlSession, args); // 執行
  }

發現關鍵點在於mapperMethod.execute(sqlSession, args)方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM