mybatis-spring干了哪些你应该知道的勾当之SqlSessionFactoryBean?

转载 :https://www.jianshu.com/p/adf2486ba56e

引子

如果你是一个服务端开发者,而你的主要语言又是Java的话,如果还不知道MyBatis和Spring这二大利器,那我只能对你说:出门右转找百度,左转找谷歌!

  • MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
  • Spring 是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式)轻量级开源框架。
  • MyBatis-Spring 帮助你将 MyBatis 代码无缝地整合到 Spring 中。 使用这个类库中的类, Spring 将会加载必要的 MyBatis 工厂类和 session 类。 这个类库也提供一个简单的方式来注入 MyBatis 数据映射器和 SqlSession 到业务层的 bean 中。 而且它也会处理事务, 翻译 MyBatis 的异常到 Spring 的 DataAccessException 异常中。最终,它并 不会依赖于 MyBatis,Spring 或 MyBatis-Spring 来构建应用程序代码。

通过上面各组件官网上的解释我们已经知道各个是干什么用的吧!

SqlSessionFactoryBean

在基本的MyBatis中,SqlSessionFactory可以使用SqlSessionFactoryBuilder来创建,而在mybatis-spring中,则使用SqlSessionFactoryBean来创建。
XML配置方式:



Java代写方式:

SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(resolver.getResources("classpath*:mappers/**/*.xml"));
SqlSessionFactory sessionFactory = factoryBean.getObject();

SqlSessionFactoryBean的类设计如下图:

 

SqlSessionFactoryBean设计图

注意: SqlSessionFactoryBean实现了Spring的FactoryBean接口这就说明了由 Spring 最终创建的 bean 不是SqlSessionFactoryBean 本身, 而是工厂类的 getObject()返回的方法的结果 ,即SqlSessionFactory对象。
具体的实现源代码如下:

public class SqlSessionFactoryBean implements FactoryBean, InitializingBean, ApplicationListener {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.1private 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 vfs;private Cache cache;private ObjectFactory objectFactory;private ObjectWrapperFactory objectWrapperFactory;// 省略getter和setter// ...@Overridepublic void afterPropertiesSet() throws Exception {// 省略属性的断言判断// ...this.sqlSessionFactory = buildSqlSessionFactory();}@Overridepublic SqlSessionFactory getObject() throws Exception {if (this.sqlSessionFactory == null) {afterPropertiesSet();}return this.sqlSessionFactory;}protected SqlSessionFactory buildSqlSessionFactory() throws IOException {Configuration configuration;// Configuration的构建优先级为:// 1. configuration属性,// 2. configLocation,MyBatis的配置文件,通常在为“WEB-INF/mybatis-configuration.xml”// 3. 如果上面二个属性都没有设置,则使用默认的配置信息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) {xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);configuration = xmlConfigBuilder.getConfiguration();} else {LOGGER.debug(() -> "Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration");configuration = new Configuration();if (this.configurationProperties != null) {configuration.setVariables(this.configurationProperties);}}// 省略部分设置configuration属性代码// ...// 这里,如果配置的xxxMapper.xml文件的路径,会循环解析xml文件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();}}}}// 这里根据configuration构建出SqlSessionFactoryreturn this.sqlSessionFactoryBuilder.build(configuration);}// ...
}

从这个类中我们可以看到,buildSqlSessionFactory干了主要的工作,从Configuration的初始化,到Configuration中各个属性值的设置,以及Mapper的xml文件解析。

属性

  • DataSource - SqlSessionFactory有一个单独的必须属性就是JDBC的DataSource.
  • mapperLocations - 如果MyBatis映射器XML文件在和映射器类相同的路径下不存在,那么就需要配置这个属性;使用这个配置有两种选择:
  1. 手动在MyBatis的XML配置文件中使用部分来指定类路径;
  2. 使用SqlSessionFactoryBean的mapperLocations属性;

至此,SqlSessionFactoryBean类的功能基本讲完了,如果你有其他想法和意见可以下在方留言~~

 

 

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部