Spring mybatis源码篇章-SqlSessionFactoryBean

https://www.cnblogs.com/question-sky/p/6602151.html

Spring+Mybatis示例内容

笔者此处只关注SqlSessionFactoryBean的配置,样例如下

    <!--数据源-->
    <bean id="dataSource-mysql" class="org.apache.commons.dbcp.BasicDataSource"> 
        <property name="driverClassName" value="${jdbc.driverClassName}" /> s
        <property name="url" value="${jdbc.url}" /> 
        <property name="username" value="${jdbc.username}" /> 
        <property name="password" value="${jdbc.password}" /> 
        <property name="initialSize" value="1" /> 
        <property name="maxActive" value="20" /> </bean> 

    <!--sqlSessionFactoryBean创建--> 
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
        <property name="dataSource" ref="dataSource-mysql" /> 
        <property name="typeAliasesPackage" value="com.du.wx.model" /> 
        <property name="mapperLocations" value="classpath:com/du/wx/resources/mapper/*.xml" /> </bean> 

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
    <!-- joggle代表接口 --> 
    <property name="basePackage" value="com.du.wx.mapper.joggle" /> </bean>

SqlSessionFactoryBean

笔者分层次来解析此类

基础内部属性

优先观察SqlSessionFactoryBean的内部属性,代码片段如下

    private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class);

    private Resource configLocation;

    private Configuration configuration;

    private Resource[] mapperLocations;

    private DataSource dataSource;

    private TransactionFactory transactionFactory;

    private Properties configurationProperties;

    private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

    private SqlSessionFactory sqlSessionFactory;

    //EnvironmentAware requires spring 3.1
    private String environment = SqlSessionFactoryBean.class.getSimpleName();

    private boolean failFast;

    private Interceptor[] plugins;

    private TypeHandler<?>[] typeHandlers;

    private String typeHandlersPackage;

    private Class<?>[] typeAliases;

    private String typeAliasesPackage;

    private Class<?> typeAliasesSuperType;

    //issue #19. No default provider.
    private DatabaseIdProvider databaseIdProvider;

    private Class<? extends VFS> vfs;

    private Cache cache;

    private ObjectFactory objectFactory;

    private ObjectWrapperFactory objectWrapperFactory;

常用的属性如下:

  • configLocation Mybatis主配置文件路径,支持classpath语法

  • mapperLocations 指定mybatis的mapper配置文件,支持classpath语法

  • dataSource 数据源

  • typeAliasesPackage 指定model层类名的别名扫描包,这与mapper配置中的paramterTyperesultType搭配使用

InitializingBean实现方法

紧接着看下其实现afterPropertiesSet()方法,代码如下

  @Override
  public void afterPropertiesSet() throws Exception {
    //datasource not allowed to be null.
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
              "Property 'configuration' and 'configLocation' can not specified with together");

    this.sqlSessionFactory = buildSqlSessionFactory();
  } 

上述在实例化SqlSessionFactoryBean前,必须确保dataSource属性已经得到配置。

具体实例化

最后查看关键实例方法buildSqlSessionFactory()方法,由于片段过长,笔者截取几段来进行讲解


Mybatis主文件加载

    Configuration configuration;

    XMLConfigBuilder xmlConfigBuilder = null;
    if (this.configuration != null) {
      configuration = this.configuration;
      if (configuration.getVariables() == null) {
        configuration.setVariables(this.configurationProperties);
      } else if (this.configurationProperties != null) {
        configuration.getVariables().putAll(this.configurationProperties);
      }
    } else if (this.configLocation != null) {
      //如果spring配置中configLocation属性不为空,则加载指定的Mybatis配置
      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      configuration = xmlConfigBuilder.getConfiguration();
    } else {
      //否则则采用默认的Mybatis配置,@see Configuration
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Property `configuration` or 'configLocation' not specified, using default MyBatis Configuration");
      }
      configuration = new Configuration();
      configuration.setVariables(this.configurationProperties);
    }

通过上述配置表明,内部属性configLocation是非必须配置项


model别名映射扫描

    if (hasLength(this.typeAliasesPackage)) {
      //截取typeAliasesPackage属性的包,支持,或;
      String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
      for (String packageToScan : typeAliasPackageArray) {
        //对应方法的目的是通过扫描包得到其包以及子包目录下的所有Class,然后为每个class注册别名  
        configuration.getTypeAliasRegistry().registerAliases(packageToScan,
        typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
        if (LOGGER.isDebugEnabled()) {
          LOGGER.debug("Scanned package: '" + packageToScan + "' for aliases");
        }
      }
    }

即对内部属性typeAliasesPackage支持,;作为分隔符以加载多个目录


mapper配置文件加载

    if (!isEmpty(this.mapperLocations)) {
      //mapperLocations
      for (Resource mapperLocation : this.mapperLocations) {
        if (mapperLocation == null) {
          continue;
        }

        try {
          //对扫描的每个配置文件进行解析,并保存其中的必要参数,后续会分析
          XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
              configuration, mapperLocation.toString(), configuration.getSqlFragments());
          xmlMapperBuilder.parse();
        } catch (Exception e) {
          throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
        } finally {
          ErrorContext.instance().reset();
        }

        if (LOGGER.isDebugEnabled()) {
          LOGGER.debug("Parsed mapper file: '" + mapperLocation + "'");
        }
      }
    } else {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Property 'mapperLocations' was not specified or no matching resources found");
      }
    }

关键处理XML配置的mapper文件,用到了mybatis的org.apache.ibatis.builder.xml.XMLMapperBuilder类进行解析


Configuration

return this.sqlSessionFactoryBuilder.build(configuration);

创建SqlSessionFactory,固然可知Configuration对象存放了关于Mybatis的很多信息

总结

1.SqlSessionFactory是创建访问数据库服务所必须的持久层

2.根据源码我们可以知道我们经常配置的参数在其中的含义

下节预告

MybatisDAO文件的解析

作者:南柯问天 出处:http://www.cnblogs.com/question-sky/ 本文版权归本人和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello_world!

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值