Mybatis工作原理

本文详细解析了MyBatis的执行流程,从SqlSessionFactory的创建到SqlSession的获取,再到MapperProxy的生成及增删改查方法的执行。深入探讨了四大对象的创建过程及其插件介入机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

运行步骤:
1、获取SqlSessionFactory对象
2、获取SqlSession对象
3、获取接口的代理对象(MapperProxy)
4、执行增删改查方法

Mybatis在四大对象的创建过程中,都会有插件进行介入。插件可以利用动态代理机制一层层的包装目标对象,从而实现在目标对象执行目标方法之前进行拦截的效果。
Mybatis允许在已映射语句执行过程中的某一点进行拦截调用
默认情况下,Mybatis允许使用插件来拦截的方法调用包括:

  • Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)
  • ParameterHandler(getParameterObject,setParameters)
  • ResultSetHandler(handleResultSets,handleOutputParameters)
  • StatementHandler(prepare,parameterize,batch,update,query)

1、获取SqlSessionFactory对象
在这里插入图片描述
在这里插入图片描述

所以在sql映射文件中对应的增删改查标签中的内容,实际上在创建SqlSessionFactory的时候就已经将其转换成为MappedStatement对象。如下是MappedStatement对象生成的具体数据:
在这里插入图片描述
最终所有的配置信息都保存在configuration中,configuration中两个非常重要的属性mappedStatements和mappedRegistry,mappedStatements存放的是所有的封装sql映射文件中的增删改查的mappedStatement,mappedRegistry中有一个Hashmap属性knownMappers属性,保存了Mapper以及其对应的MapperProxyFactory,包括全局配置信息以及sql映射文件信息,如下;
在这里插入图片描述
总结:把配置文件的信息解析并保存在Configuration对象中,返回包含Configuration的DefaultSqlSessionFactory对象。

2、获取SqlSession对象
在这里插入图片描述
在这里插入图片描述

上面在全局配置文件中通过DefaultExecutorType设置ExecutorType,默认是SIMPLE,上面图中写错了。最终返回的是DefaultSqlSession,返回的DefaultSqlSession包含了创建的Executor和Configuration。

3、获取接口的代理对象(MapperProxy)
在这里插入图片描述
在这里插入图片描述

DefaultSqlSession

@Override
  public <T> T getMapper(Class<T> type) {
    return configuration.<T>getMapper(type, this);
  }

Configuration

  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return mapperRegistry.getMapper(type, sqlSession);
  }

MapperRegistry

  @SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) 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);
    }
  }

MapperProxyFactory

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

4、执行增删改查方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

整个流程总结:
1、根据配置文件(全局,sql映射文件)初始化Configuration对象
2、创建一个DefaultSqlSession对象
里面包含Configuration对象和Executor(根据全局配置文件中的defaultExecutorType创建对应Executor对象)
3、DefaultSqlSession.getMapper(),拿到Mapper接口对应的MapperProxy
4、MapperProxy里面有DefaultSqlSession
5、执行增删改查方法:

  • 调用DefaultSqlSession的增删改查(Executor)
  • 创建一个StatementHandler对象(同时也会创建ParameterHandler和ResultSetHandler对象)
  • 调用StatementHandler预编译参数以及设置参数值(ParameterHandler来给sql设置参数)
  • 调用StatementHandler的增删改查方法
  • ResultSetHandler封装结果

注意:四大对象,Executor,ParameterHandler,ResultSetHandler,StatementHandler在创建的时候都会调用一个interceptorChain.pluginAll(四大对象)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值