mybatis查询语句的背后揭秘

  


  

  

在先了解mybatis查询之前,先大致了解下以下代码的为查询做了哪些铺垫,在这里我们要事先了解,myabtis会默认使用DefaultSqlSessionFactory作为sqlSessionFactory的实现类,而sqlSession的默认实现类为DefaultSqlSession

        公共静态SqlSessionFactory getSessionFactory()抛出IOException {   读者读者=Resources.getResourceAsReader (“mybatis/mybatis-config.xml”);   SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder ();   返回builder.build(读者);   }      

获取mybatis的配置文件流,交给sqlSessionFactoryBuilder进行解析,在这里只会涉及到一部分,具体,请大家移步mybatis源码进行分析

  

解析大致步骤(以下说的配置文件,是mybatis配置数据库连接信息的那个配置文件,不是mapper.xml文件)

  

解析配置文件的核心类在XMLConfigBuilder类中,

  

代码如下

        公共配置parse () {   如果(解析){   把新BuilderException(“每个XMLConfigBuilder可以>   公共空间parse () {//也就是检测配置文件配置的mapper节点有没有加载到配置类中,防止重复加载   如果(! configuration.isResourceLoaded(资源)){   configurationElement (parser.evalNode("/映射器"));   configuration.addLoadedResource(资源);//这个是绑定,映射器接口的,当处理成功,在配置类中的mapper注册器中,会添加一个映射器   bindMapperForNamespace ();   }      parsePendingResultMaps();//解析resultMap节点   parsePendingCacheRefs ();//解析缓存节点,如& lt; cache-ref/比;   parsePendingStatements();//解析选择|更新等节点,并封装成mappedStatement类   }      

其中bindMapperForNamespace()方法的操作会导致以下结果

  

在配置类中的MapperRegistry属性中添加一个映射器,结果存储在MapperRegistry类的一个地图中,键为mapper类的值为一个代理工厂,负责产生mapper接口代理类。

  

  

当我们使用要使用mybatis进行查询操作,无非大致就是两种方式

     /* *   *通过mapper接口形式查询数据   */@Test   公共空间testSelectByMapper()抛出IOException {   .openSession SqlSession SqlSession=MybatisUtil.getSessionFactory () ();   usermap mapper=sqlSession.getMapper (UserMapper.class);   用户用户=mapper.selectByPrimaryKey (10);   System.out.println(用户);   sqlSession.close ();   }/* *   *通过mapper接口的全限定名来进行查询   * @throws IOException   */@Test   公共空间testSelectByString()抛出IOException {   SqlSessionFactory sessionFactory=MybatisUtil.getSessionFactory ();   SqlSession SqlSession=sessionFactory.openSession ();   用户用户=sqlSession.selectOne (“com.mybatis.demo.mybatisdemo.mapper.UserMapper.selectByPrimaryKey”, 10);   System.out.println(用户);   sqlSession.close ();   }      

先来看第一种的分析,当我们点击getMapper进去,它会去调用配置类中getMapper方法,就如上面介绍的解析出mapper节点后,会存储在配置类中的mapper注册器中,

     //defaultSqlSession类   公共& lt; T>T getMapper (Class类型){   返回配置灵活,T> getMapper(类型,);   }//配置类   公共& lt; T>T getMapper (Class类型,SqlSession SqlSession) {   mapperRegistry返回。getMapper(类型、sqlSession);   }//最终获取映射器对象的方法,其主要是创建一个映射器代理工厂,我们都知道mybatis的mapper接口是没有实现类的,//但是我们直接查询是能获取数据,这里起作用的就是代理(采用的是jdk动态代理)   公共& lt; T>T getMapper (Class类型,SqlSession SqlSession) {   最后MapperProxyFactorymapperProxyFactory=(MapperProxyFactory      

然后最终会经过代理类MapperProxy的调用方法,进行返回结果。在这里为了更好的能理解这个类,举个例子,步骤如下

  

先创建一个接口,再使用一个类去实现java jdk的代理的核心接口InvocationHandler,

        公共接口TestMapper {         用户findByUserId(整数id);   }            公共类MapperProxyTest实现InvocationHandler {      私人Class

mybatis查询语句的背后揭秘