MyBatis的解析和运行原理

MyBatis的解析和运行原理

  1. 了解MyBatis解析配置文件的大致过程
  2. 掌握MyBatis底层映射保存的数据结构(MappedStatement,SqlSource,BoundSql)及其内容
  3. 了解MyBatis Mapper的运行原理
  4. 掌握SqlSession运行原理
  5. 掌握SqlSession下四大对象的设计原理和具体方法的作用

MyBatis的运行过程分为两大步:第1步,读取配置文件缓存到Configuration对象,用以
创建SqlSessionFactory;第2步,SqlSession的执行过程。

构建SqlSessionFactory过程

最重要的功能是提供MyBatis的核心接口SqlSession

采用Builder模式去创建SqlSessionFactory,在实际中可以通过SqlSessionFactoryBuilder去构建,其构建分为两步:

  1. 通过 org.apache.ibatis.builder.xml.XMLConfigBuilder 解析配置的 XML 文件,
    读出所配置的参数,并将读取的内容存入 org.apache.ibatis.session.Configuration 类对象中。而Configuration 采用的是单例模式,几乎所有 MyBatis 配置内容都会存放在这个单例对象中,以便后续将这些内容读出。
  2. 使用 Configuration 对象去创建 SqlSessionFactory。MyBatis中的SqlSessionFactory
    是一个接口,而不是一个实现类,为此 MyBatis 提供了一个默认的实现类
    org.apache.ibatis.session.defaults.DefaultSqlSessionFactory 。在大部分情况下都没有必要自己去创建新 SqlSessionFactory 实现类。
构建Configuration

Configuration是提供XMLConfigBuilder去构建的,首先读出所以的XML配置的信息,然后把它们解析并保存在Configuration单例中。

构建映射器的内部组成

一般而言,在MyBatis中一条SQL与它相关的配置是由3个部分组成的,它们分别是MappedStatement,
SqlSource和BoundSql

  • MappedStatement作用是保存一个映射器节点(select | insert | delete | update)的内容。它还有一个重要的属性sqlSource。MyBatis通过读取它来获得某条SQL配置的所有信息。
  • SqlSource是提供BoundSql对象的地方,它是MappedStatement的一个属性。
    他的作用是根据上下文和参数解析生成需要的SQL。
  • BoundSql是一个结果对象,也就是SqlSource通过对SQL和参数的联合解析得到的SQL和参数,它是建立SQL和参数的地方。主要会提供三个属性:parameterMappings、parameterObject和sql。
    • parameterObject为参数本身,可以传递简单对象,POJO或者Map,@Param
      注解的参数。
    • parameterMappings是一个List,他的每个元素都是ParameterMapping对象。对象会描述参数,参数包括属性名称、表达式、javaType、jdbcType、typeHandler等重要信息。
    • sql属性就是书写在映射器里面的一条被SqlSource解析后的SQL。
构建SqlSessionFactory

SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession运行过程

映射器(Mapper)的动态代理

RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class)
MyBatis源码是如何实现getMapper方法的:

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

显然运用到了Configuration对象的getMapper方法,追踪这个方法:

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

运用了映射器的注册器MapperRegistry来获取对应的接口对象,如下:

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
        if (mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        } else {
            try {
                return mapperProxyFactory.newInstance(sqlSession);
            } catch (Exception var5) {
                throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
            }
        }
    }

首先判断是否注册一个Mapper,如果没有则会抛出异常;如果有,就会启用MapperProxyFactory

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值