当前位置 主页 > 网站技术 > 代码类 >

    MyBatis执行Sql的流程实例解析

    栏目:代码类 时间:2019-12-23 21:08

    这篇文章主要介绍了MyBatis执行Sql的流程实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    本博客着重介绍MyBatis执行Sql的流程,关于在执行过程中缓存、动态SQl生成等细节不在本博客中体现,相应内容后面再单独写博客分析吧。

    还是以之前的查询作为列子:

    public class UserDaoTest {
    
      private SqlSessionFactory sqlSessionFactory;
    
      @Before
      public void setUp() throws Exception{
        ClassPathResource resource = new ClassPathResource("mybatis-config.xml");
        InputStream inputStream = resource.getInputStream();
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      }
    
      @Test
      public void selectUserTest(){
        String id = "{0003CCCA-AEA9-4A1E-A3CC-06D884BA3906}";
        SqlSession sqlSession = sqlSessionFactory.openSession();
        CbondissuerMapper cbondissuerMapper = sqlSession.getMapper(CbondissuerMapper.class);
        Cbondissuer cbondissuer = cbondissuerMapper.selectByPrimaryKey(id);
        System.out.println(cbondissuer);
        sqlSession.close();
      }
    
    }

    之前提到拿到sqlSession之后就能进行各种CRUD操作了,所以我们就从sqlSession.getMapper这个方法开始分析,看下整个Sql的执行流程是怎么样的。

    获取Mapper

    进入sqlSession.getMapper方法,会发现调的是Configration对象的getMapper方法:

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
      //mapperRegistry实质上是一个Map,里面注册了启动过程中解析的各种Mapper.xml
      //mapperRegistry的key是接口的全限定名,比如com.csx.demo.spring.boot.dao.SysUserMapper
      //mapperRegistry的Value是MapperProxyFactory,用于生成对应的MapperProxy(动态代理类)
      return mapperRegistry.getMapper(type, sqlSession);
    }

    进入getMapper方法:

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
      final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
      //如果配置文件中没有配置相关Mapper,直接抛异常
      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的newInstance方法:

    public class MapperProxyFactory<T> {
    
     private final Class<T> mapperInterface;
     private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();
    
     public MapperProxyFactory(Class<T> mapperInterface) {
      this.mapperInterface = mapperInterface;
     }
    
     public Class<T> getMapperInterface() {
      return mapperInterface;
     }
    
     public Map<Method, MapperMethod> getMethodCache() {
      return methodCache;
     }
    
     //生成Mapper接口的动态代理类MapperProxy
     @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<T>(sqlSession, mapperInterface, methodCache);
      return newInstance(mapperProxy);
     }
    
    }