1. MapperProxyFactory 代理
Mapper 接口代理对象的生成类,当通过Sqlsession拿到Mapper接口对象,这个Mapper接口是JDK的动态代理生成的代理对象 【Configuration 中的MapperRegistry 中 knownMappers中存放 mapper接口的 Class<?> 和 代理对象工厂类的关系】从而在访问的时候:configurationb.getMapper(class<?>, sqlSession) -> MapperRegistry.knownMappers 容器拿到对应的 MapperProxyFactory 然后 调用newInstance() 方法创建出代理对象 MapperProxy
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
调用其查询方法(DDL数据库操作的方法)走到代理对象 invoke() 方法,然后由 MapperMethod(对invoke中Method对象即调用方法的包装)MapperMethod.execute()
2. MapperMethod 根据DDL 类型(select/insert/delete/updae)执行不同的方法,select 方法最复杂
MapperMethod 包含了 执行的 sql 语句 和 方法的信息【返回值类型,参数,key, 分页相关】
private final SqlCommand command;
private final MethodSignature method;
然后调用对应的DefaultSqlsession的 selectOne()/selectLIst(),
3. DefaultSqlSession
DefaultSqlSession 通过 id 【namespace+方法的id】获取到对应的MapperedStatement对象,主要封装 <select>标签的属性,id,resultType, ResultMaps parameterType , 缓存等】
然后就是执行 BaseExecutor 的查询【开启了二级缓存CachingExecutor】->query() .. -> doQuery() 拿到 StatementHandler【mapperstatement中 拿到 Configuration.newStatementHanlder()】,这里使用到了静态代理 RoutingStatement Handler ->默认创建 PrepareStatementHandler
doQuery() 有常用的几种实现 SimpeExecutor/ BatchExecutor/ ReuseExecutor
private String resource;
private Configuration configuration;
private String id;
private Integer fetchSize;
private Integer timeout;
private StatementType statementType;
private ResultSetType resultSetType;
private SqlSource sqlSource;
private Cache cache;
private ParameterMap parameterMap;
private List<ResultMap> resultMaps;
private boolean flushCacheRequired;
private boolean useCache;
private boolean resultOrdered;
private SqlCommandType sqlCommandType;
private KeyGenerator keyGenerator;
private String[] keyProperties;
private String[] keyColumns;
private boolean hasNestedResultMaps;
private String databaseId;
private Log statementLog;
private LanguageDriver lang;
private String[] resultSets;
4. PrepareStatementHandler 主要生成 statement 执行 sql【用到 BaseStatementHandler.prepare()】
首先会对statement进行初始化 prepateStement() -> 拿到 Connection -> handler.prepare() 创建 Statement->使用模板设计模式,instantiateStatement() 钩子方法【SimpleStatementHandler/CallableStatementHandler/PrepareStatementHandler】创建statement对象返回, 设置参数【PrepareStatement 设置占位符】,DefaultParemeterHandler 【用到MetaObject 对参数设值反射】
5. DefaultParameterHandler 对占位符参数进行设值
用到 mybatis 的反射类MetaObject ,然后执行sql 操作,对返回值处理 ResultSetHandler
6. DefaultResultSetHandler
字段映射嵌套查询
总结:
* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mybatis 请求流程和数据处理 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> * 1. MapperProxyFactory 动态代理 产生 MapperProxy 代理对象 * DefaultSqlSession 中持有Configuration对象实例 * 从Sqlsession获取到Mapper接口对象,这个接口对象是MapperProxyFactory对象,用于产生 Mapper接口的代理对象MapperProxy * 2. MapperProxy InvocationHandler -> invoke() * 调用invoke()方法 将Method对象包装成 MapperMethod 对象 * MapperMethod -> execute() * 3. MapperMethod 根据不同command类型 [select/insert/update/delete] 进行不同操作 * select 较复杂 * 调用 DefaultSqlSession . selectOne/selectList * 4. DefaultSqlSession * selectList() configuration.根据【namespace.方法名】获取得到 MappedStatement * BaseExecutor.query() -> .... -> doQuery() * 5. BaseExecutor.query() -> SimpleExecutor.doQuery() * 首先通过静态代理 RoutingStatementHandler -> statementHandler * (1) PrepareStatementHandler (默认) * (2) SimpleStatementHandler * (3) CallableStatementHandler * 同时添加拦截器链 * * prepareStatement() -> hanlder.prepare() -> 创建Statement 对象 * 默认创建 PreparedStatement * <<<<< 谁能穿件statement connection 获取 Connection对象 如归日志级别为Debug 会创建 带日志功能的 Connection >>>> * handler.prepare() 使用 模板设计 -> 钩子方法有子类实现 * instantiateStatement() 模板 钩子方法 * * 设置参数(占位符处理) 引出 ParameterHandler * 反射 MetaObject * 6. ParameterHandler 设置 占位符 * 执行 查询 handler.query(); statement.execute() 返回结果 引出 ResultSetHandler * 7. ResultSetHandler 处理结果集 * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mybatis 请求流程和数据处理 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>