在先了解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) { 最后MapperProxyFactory mapperProxyFactory=(MapperProxyFactory 然后最终会经过代理类MapperProxy的调用方法,进行返回结果。在这里为了更好的能理解这个类,举个例子,步骤如下
先创建一个接口,再使用一个类去实现java jdk的代理的核心接口InvocationHandler,
公共接口TestMapper { 用户findByUserId(整数id); }公共类MapperProxyTest实现InvocationHandler { 私人Classmybatis查询语句的背后揭秘