zoukankan      html  css  js  c++  java
  • Mybaits源码分析九之sql执行流程

    mybatis的Demo中的代码段为:

    1 SubjectDao subjectDao=sqlSession.getMapper(SubjectDao.class);

    对应的源码为:

    1   @Override
    2   public <T> T getMapper(Class<T> type) {
    3     return configuration.<T>getMapper(type, this);
    4   }
    1 public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    2     return mapperRegistry.getMapper(type, sqlSession);
    3   }
     1 @SuppressWarnings("unchecked")
     2   public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
     3     //创建mapper代理工厂 type的值为UserDao接口类实例
     4     final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
     5     if (mapperProxyFactory == null) {
     6       throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
     7     }
     8     try {
     9      //返回Mapper的代理实例
    10       return mapperProxyFactory.newInstance(sqlSession);
    11     } catch (Exception e) {
    12       throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    13     }
    14   }
    1 public T newInstance(SqlSession sqlSession) {
    2     final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    3     //返回的MapperProxy实例
    4     return newInstance(mapperProxy);
    5   }

    myBatis指明具体调用的接口

    1  List<Subject> subjectList=subjectDao.selectSubject01();

    其源码分析为因为之前返回的时mapper的类实例,调用具体方法会使用invoke方法即:

     1   @Override
     2   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     3     try {
     4       //判断这个类是否是方法类的class对象
     5       if (Object.class.equals(method.getDeclaringClass())) {
     6         return method.invoke(this, args);
     7       } else if (isDefaultMethod(method)) {
     8         //调用默认方法
     9         return invokeDefaultMethod(proxy, method, args);
    10       }
    11     } catch (Throwable t) {
    12       throw ExceptionUtil.unwrapThrowable(t);
    13     }
    //将方法加入到此方法
    14 final MapperMethod mapperMethod = cachedMapperMethod(method);
    //调用执行器
    15 return mapperMethod.execute(sqlSession, args); 16 }

    此执行器会判断此接口是执行哪一种类型的sql,

     1 public Object execute(SqlSession sqlSession, Object[] args) {
     2     Object result;
     3     switch (command.getType()) {
     4       case INSERT: {
     5         Object param = method.convertArgsToSqlCommandParam(args);
     6         result = rowCountResult(sqlSession.insert(command.getName(), param));
     7         break;
     8       }
     9       case UPDATE: {
    10         Object param = method.convertArgsToSqlCommandParam(args);
    11         result = rowCountResult(sqlSession.update(command.getName(), param));
    12         break;
    13       }
    14       case DELETE: {
    15         Object param = method.convertArgsToSqlCommandParam(args);
    16         result = rowCountResult(sqlSession.delete(command.getName(), param));
    17         break;
    18       }
    19       case SELECT:
    20         if (method.returnsVoid() && method.hasResultHandler()) {
    21           executeWithResultHandler(sqlSession, args);
    22           result = null;
    23         } else if (method.returnsMany()) {
    24           result = executeForMany(sqlSession, args);
    25         } else if (method.returnsMap()) {
    26           result = executeForMap(sqlSession, args);
    27         } else if (method.returnsCursor()) {
    28           result = executeForCursor(sqlSession, args);
    29         } else {
    30           Object param = method.convertArgsToSqlCommandParam(args);
    31           result = sqlSession.selectOne(command.getName(), param);
    32         }
    33         break;
    34       case FLUSH:
    35         result = sqlSession.flushStatements();
    36         break;
    37       default:
    38         throw new BindingException("Unknown execution method for: " + command.getName());
    39     }
    40     if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
    41       throw new BindingException("Mapper method '" + command.getName() 
    42           + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
    43     }
    44     return result;
    45   }
    生于忧患,死于安乐
  • 相关阅读:
    LOJ#10106. 「一本通 3.7 例 2」单词游戏
    小木棍(爆搜减枝)
    倍增求lca(模板)
    2018年第九届蓝桥杯C/C++A组省赛(最后一题)
    LOJ#10172. 「一本通 5.4 练习 1」涂抹果酱
    【[APIO/CTSC2007]动物园】状压DP
    c++滚动数组
    状态压缩入门(附经典题目和题解)
    小 M 的算式(dfs)
    P与NP问题详解
  • 原文地址:https://www.cnblogs.com/songlove/p/14611507.html
Copyright © 2011-2022 走看看