• 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   }
    生于忧患,死于安乐
  • 相关阅读:
    Leetcode:50. Pow(x, n)
    loj 2759「JOI 2014 Final」飞天鼠
    bzoj 3569 DZY Loves Chinese II
    CF407D Largest Submatrix 3
    bzoj 3837 pa2013 Filary
    bzoj 4722 由乃
    CF1105E Helping Hiasat
    loj 6043「雅礼集训 2017 Day7」蛐蛐国的修墙方案
    luogu P2605 [ZJOI2010]基站选址
    luogu P3226 [HNOI2012]集合选数
  • 原文地址:https://www.cnblogs.com/songlove/p/14611507.html
Copyright © 2020-2023  润新知