博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mybatis源码阅读之三
阅读量:6982 次
发布时间:2019-06-27

本文共 3206 字,大约阅读时间需要 10 分钟。

hot3.png

    由前面的系列二分析到MapperMethod的execute方法,我们接着分析MapperMethod。如下List-1:

    List-1

public class MapperMethod {  private final SqlCommand command;  private final MethodSignature method;  public MapperMethod(Class
mapperInterface, Method method, Configuration config) { this.command = new SqlCommand(config, mapperInterface, method); this.method = new MethodSignature(config, mapperInterface, method); } public Object execute(SqlSession sqlSession, Object[] args) { Object result; switch (command.getType()) { case INSERT: { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.insert(command.getName(), param)); break; } case UPDATE: { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.update(command.getName(), param)); break; } case DELETE: { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.delete(command.getName(), param)); break; } case SELECT: if (method.returnsVoid() && method.hasResultHandler()) { executeWithResultHandler(sqlSession, args); result = null; } else if (method.returnsMany()) { result = executeForMany(sqlSession, args); } else if (method.returnsMap()) { result = executeForMap(sqlSession, args); } else if (method.returnsCursor()) { result = executeForCursor(sqlSession, args); } else { Object param = method.convertArgsToSqlCommandParam(args); result = sqlSession.selectOne(command.getName(), param); } break; case FLUSH: result = sqlSession.flushStatements(); break; default: throw new BindingException("Unknown execution method for: " + command.getName()); } if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) { throw new BindingException("Mapper method '" + command.getName() + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } return result; }...

    List-1中,根据类型来调用不同的处理,我们以insert为例子分析,调用的就是如下的List-2,首先将传入Mapper方法上的参数转换为SQL参数,之后调用SqlSession的insert方法,注意这个SqlSession是SqlSessionTemplate,我们来看SqlSessionTemplate的insert方法,如List-3:

    List-2

case INSERT: {    Object param = method.convertArgsToSqlCommandParam(args);    result = rowCountResult(sqlSession.insert(command.getName(), param));    break;}

    List-3

public int insert(String statement, Object parameter) {    return this.sqlSessionProxy.insert(statement, parameter);}

如下图1所示,

                                                             图1

  •     步骤2调用的SqlSessionInterceptor是JDK的代理类;
  •     步骤4中,做了很多事情,比如不同类型Executor的生成就是在里面;
  •     步骤13中,会先清空缓存——因为我们目前看的是insert更新操作;
  •     步骤17中调用的StatementHandler默认是RoutingStatementHandler,用了Delegate设计模式,默认情况下委托给PreparedStatementHandler;
  •     步骤23中,涉及了KeyGenerator,所以后面看mybatis中返还主键值看这里;

    步骤17中,RoutingStatementHandler使用了代理模式,将事情全部委托给第三方来做。

    步骤1中调用的SqlSessionTemplate,以Template结尾,看着像使用Template模板模式,但是个人觉得是使用了代理模式,因为它内部实现上,大部分事情都委托给了内部类SqlSessionInterceptor。

    值得一提的是,BaseExecutor使用了Template模板模式,定义了执行步骤,然后具体实现由其实现类了实现。

    图1的过程中,涉及了事物,使用的是Spring的事物管理。

转载于:https://my.oschina.net/u/2518341/blog/3050615

你可能感兴趣的文章
《数据结构》例1.3
查看>>
堆和栈的区别 (转贴)
查看>>
OpenSSL s_server / s_client 应用实例
查看>>
微信小程序开发工具(0.9.092300)下载地址,分享给没有公众号的小伙伴
查看>>
项目中的常见算法
查看>>
(转)GCT之逻辑经验总结(拿来主义)
查看>>
虚拟继承中子类和父类的构造函数顺序1
查看>>
js错误: Unexpected number in JSON at position 2792 value里面有双引号怎么解决
查看>>
(实践篇)剖析最近项目使用的一个框架
查看>>
usaco Typo
查看>>
字符串
查看>>
创建对象的三种方式
查看>>
spring学习之spring 插件 for eclipse
查看>>
js-sha256源码
查看>>
运维笔试题
查看>>
dispaly、position、float之间的关系与相互作用
查看>>
MyEclipse加入jquery.js文件missing semicolon的错误
查看>>
axis1.4生成客户端
查看>>
地区选择控件杂记
查看>>
来自工程师的8项Web性能提升建议
查看>>