Mybatis执行sql流程(一)
文章目录
- 第一行:
- 第二行:
代码中的两行代码是如何执行的?
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.selectById(userId);
第一行:
获取 Mapper 接口的代理对象,调用链如下:
SqlSession.getMapper() → Configuration.getMapper() → MapperRegistry.getMapper() // 使用map做了缓存,若没有则继续向下→ MapperProxyFactory.newInstance() // 使用 JDK 动态代理生成 Mapper 接口的代理对象。即返回的是一个动态生成代理类对象。具体的代理过程此处不详细介绍,在后文。
第二行:
执行SQL:动态代理拦截方法调用。
userMapper.selectById(userId);
上述得知userMapper对象是代理类对象,此处调用的selectById
方法就是代理类中实现的接口方法(当然不是具体的实现内容,具体的实现内容在InvocationHandler与JDK动态代理相关)参考JDK动态代理
// 例如:执行userMapper.selectUserById(1);
MapperProxy.invoke() // MapperProxy 就是InvocationHandler的实现,即具体实现内容在此。在调用链中还涉及到二级缓存的事情,后续说明→ MapperMethod.execute() // MapperMethod 将方法调用转为SqlSession的操作,如selectOne/insert等→ SqlSession.selectOne() → Executor.query() // 有多种执行器,后续详细说明→ MappedStatement.getBoundSql() → query() // 此处涉及到一级缓存的事情,后续说明;如果没有命中一级缓存,则查询数据库→ Executor.prepareStatement() // 此处涉及到TypeHandler,将对应的java数据转化为sql类型的数据→ StatementHandler.query()→ PreparedStatement.execute() // 执行sql→ ResultHandler.handleResultSets() // 此处涉及到TypeHandler,将结果集转化为java类型的数据
相关内容:
JDK代理
Mybatis加载Mapper
MapperRegistry
MyBatis中JDK动态代理
Mybatis之MapperProxy
Mybatis之MapperMethod
Mybatis之Executor执行器
Mybatis之StatementHandler
Mybatis之KeyGenerator