博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Mybatis】- sqlSession工作流程
阅读量:7094 次
发布时间:2019-06-28

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

hot3.png

Mybatis Session工作过程

测试代码

sqlSessionFactory.openSession(false).getMapper(StudentMapper.class).findStudentById(id)

核心方法:org.apache.ibatis.session.Configuration#getMapper

public 
T getMapper(Class
type, SqlSession sqlSession) { //从Mybatis初始化过程中绑定的名称空间和接口类,获取接口工厂 final MapperProxyFactory
mapperProxyFactory = (MapperProxyFactory
) 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); } }

动态代理工厂

public class MapperProxyFactory
{ private final Class
mapperInterface; private final Map
methodCache = new ConcurrentHashMap
(); public MapperProxyFactory(Class
mapperInterface) { this.mapperInterface = mapperInterface; } public Class
getMapperInterface() { return mapperInterface; } public Map
getMethodCache() { return methodCache; } @SuppressWarnings("unchecked") protected T newInstance(MapperProxy
mapperProxy) { //JDK动态代理 return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); } public T newInstance(SqlSession sqlSession) { final MapperProxy
mapperProxy = new MapperProxy
(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); }}

动态代理对象:MapperProxy

[@Override](https://my.oschina.net/u/1162528)  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    try {      if (Object.class.equals(method.getDeclaringClass())) {        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);    return mapperMethod.execute(sqlSession, args);  }

sql操作

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

org.apache.ibatis.binding.MapperMethod#executeForMany

private 
Object executeForMany(SqlSession sqlSession, Object[] args) { List
result; Object param = method.convertArgsToSqlCommandParam(args); if (method.hasRowBounds()) { RowBounds rowBounds = method.extractRowBounds(args); result = sqlSession.
selectList(command.getName(), param, rowBounds); } else { result = sqlSession.
selectList(command.getName(), param); } // issue #510 Collections & arrays support if (!method.getReturnType().isAssignableFrom(result.getClass())) { if (method.getReturnType().isArray()) { return convertToArray(result); } else { return convertToDeclaredCollection(sqlSession.getConfiguration(), result); } } return result; }//具体的操作通过Executor操作,本质底层也是JDBC操作,只是通过configuration配置按照业务进行数据转换[@Override](https://my.oschina.net/u/1162528) public
List
selectList(String statement, Object parameter, RowBounds rowBounds) { try { MappedStatement ms = configuration.getMappedStatement(statement); return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }

转载于:https://my.oschina.net/yangzhiwei256/blog/3031259

你可能感兴趣的文章
骆驼命名发
查看>>
我的友情链接
查看>>
liunx服务使用(mysql数据库的安装和传说中的LAMP的安装【论坛的搭建】)
查看>>
码农,你真的准备好转产品了吗?
查看>>
TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
查看>>
LOVEFiLM Cashback
查看>>
shell-scripts,FTP自动化上传脚本,可循环,直到上传成功为止
查看>>
使用shell脚本实现加法乘法运算
查看>>
jQuery插件开发1:分页条
查看>>
pycharm调试edx环境搭建
查看>>
11.10/11.11/11.12 安装PHP5 11.13 安装PHP7
查看>>
HQL:实用技术
查看>>
css基本使用
查看>>
使用canvas画圆
查看>>
基础设施ddos防御
查看>>
Django之分页功能实例
查看>>
【机器学习PAI实战】—— 玩转人工智能之利用GAN自动生成二次元头像
查看>>
zookeeper集群的安装和配置
查看>>
tomcat学习笔记之默认连接器
查看>>
基于UDP的服务器和客户端之间的通信
查看>>