您的位置:首页 > 编程语言 > Java开发

Spring mybatis源码篇章-SqlSessionFactoryBean

2017-03-22 21:21 751 查看

前言:通过实例结合源码的方式解读,其中涉及到的文件来自于笔者的Github毕设项目,引用的jar包为
mybatis-spring-1.3.0.jar



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配置中的paramterType和resultType搭配使用


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文件的解析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: