Mybatis3源码分析(一):从sqlSession说起

来源:互联网 发布:199it大数据工具导航 编辑:程序博客网 时间:2024/05/17 04:56
  


分析MyBatis3的源码首先得从sqlSessionFactory开始,先来看一段spring配置文件中Mybaits的sqlSessionFactory的配置。

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  destroy-method="close">     <property name="driverClassName" value="${jdbc.driver}" />     <property name="url" value="${jdbc.url}" />     <property name="username" value="${jdbc.username}" />     <property name="password" value="${jdbc.password}" />  </bean>  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">     <property name="dataSource" ref="dataSource" />   <property name="configLocation" value="classpath:configuration.xml"></property>    <property name="mapperLocations" value="classpath:com/tiantian/mybatis/mapper/*.xml"/>     <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" />  </bean><bean id="blogMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">         <property name="mapperInterface"             value="com.tiantian.mybatis.mapper.BlogMapper" />        <property name="sqlSessionFactory" ref="sqlSessionFactory" />  </bean>   

    spring会调用sqlSessionFactory的无参构造函数创建实例,并将dataSource和映射文件路径注入进去初始化sqlSessionFactory。这里的SqlSessionFactoryBean的实现依赖于mybatis社区自行开发的支持包,我们来看看它是怎么读取xml配置文件创建sessionFactory的:

protected SqlSessionFactory buildSqlSessionFactory() throws IOException {    //代表配置的对象    Configuration configuration;    //xml配置创建者    XMLConfigBuilder xmlConfigBuilder = null;    //spring中注入的配置文件路径,如果不存在使用默认配置    if (this.configLocation != null) {      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);      configuration = xmlConfigBuilder.getConfiguration();    } else {      if (logger.isDebugEnabled()) {        logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration");      }      configuration = new Configuration();      configuration.setVariables(this.configurationProperties);    }    //如果配置了objectFactory使用此配置类    if (this.objectFactory != null) {      configuration.setObjectFactory(this.objectFactory);    }    //同上    if (this.objectWrapperFactory != null) {      configuration.setObjectWrapperFactory(this.objectWrapperFactory);    }    //如果配置了typeAliases(实体类别名标签)的基包则不用在configuration文件中配置    if (hasLength(this.typeAliasesPackage)) {      String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);      for (String packageToScan : typeAliasPackageArray) {        configuration.getTypeAliasRegistry().registerAliases(packageToScan,                typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);        if (logger.isDebugEnabled()) {          logger.debug("Scanned package: '" + packageToScan + "' for aliases");        }      }    }    //如果是直接配置的实体类别名则在配置对象中注册    if (!isEmpty(this.typeAliases)) {      for (Class<?> typeAlias : this.typeAliases) {        configuration.getTypeAliasRegistry().registerAlias(typeAlias);        if (logger.isDebugEnabled()) {          logger.debug("Registered type alias: '" + typeAlias + "'");        }      }    }    //是否配置mybaits的一些插件    if (!isEmpty(this.plugins)) {      for (Interceptor plugin : this.plugins) {        configuration.addInterceptor(plugin);        if (logger.isDebugEnabled()) {          logger.debug("Registered plugin: '" + plugin + "'");        }      }    }    //是否配置typeHandler的基包    if (hasLength(this.typeHandlersPackage)) {      String[] typeHandlersPackageArray = tokenizeToStringArray(this.typeHandlersPackage,          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);      for (String packageToScan : typeHandlersPackageArray) {        configuration.getTypeHandlerRegistry().register(packageToScan);        if (logger.isDebugEnabled()) {          logger.debug("Scanned package: '" + packageToScan + "' for type handlers");        }      }    }    //是否直接配置了typeHandler    if (!isEmpty(this.typeHandlers)) {      for (TypeHandler<?> typeHandler : this.typeHandlers) {        configuration.getTypeHandlerRegistry().register(typeHandler);        if (logger.isDebugEnabled()) {          logger.debug("Registered type handler: '" + typeHandler + "'");        }      }    }    //如果xmlConfigBuilder存在则开始分析创建Configuration对象    if (xmlConfigBuilder != null) {      try {        xmlConfigBuilder.parse();        if (logger.isDebugEnabled()) {          logger.debug("Parsed configuration file: '" + this.configLocation + "'");        }      } catch (Exception ex) {        throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);      } finally {        ErrorContext.instance().reset();      }    }    //事务工厂是否配置    if (this.transactionFactory == null) {      this.transactionFactory = new SpringManagedTransactionFactory();    }    //设置Configuration的环境对象    Environment environment = new Environment(this.environment, this.transactionFactory, this.dataSource);    configuration.setEnvironment(environment);     if (this.databaseIdProvider != null) {      try {        configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));      } catch (SQLException e) {        throw new NestedIOException("Failed getting a databaseId", e);      }    }    //是否配置mapperLocations,如果存在解析创建这些mapper,mapper是mybaits管理各种sql的容器    if (!isEmpty(this.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");      }    }    //创建sqlSessionFactoryBean    return this.sqlSessionFactoryBuilder.build(configuration);  }

    从mybatis创建sqlSessionFactoryBean的过程可以看出,mybaits默认使用spring的事务管理功能或者由第三方实现,它自身并没有提供事务管理能力。其次,它拥有跟其它框架差不多的解析xml过程,都是将xml解析成一个Configuration对象随时取用。到这里我们就得到了一个sqlSessionFactoryBean对象(实际是mybatis本身的DefaultSqlSessionFactory对象),我们可以在DAO中注入这个对象并利用openSession的方法获取SqlSession对象从而进行各种数据库操作。

0 0
原创粉丝点击