mybatis 查询请求流程详解

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 请求流程和数据处理 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值