mybatis与spring的整合之MapperScannerConfigurer
缘起: 之前有讲到用
xml配置
单个映射接口
mybatis与spring的整合之MapperFactoryBean和用
注解配置
多个映射接口
mybatis与spring的整合之ClassPathMapperScanner,它们都是用
java(注解)编程
形式写
sql
,这样不易于编写复杂的语句,而且可读性不强,不易于扩展。本篇讲解用
xml
形式编写
sql
语句,是如何与
Spring结合的源码分析。
项目结构
拿许雪里的项目举例
编写mapper接口
也就是 dao
层
例如:不在接口层面用注解编写sql
语句
public interface XxlJobGroupDao {
public List<XxlJobGroup> findAll();
public List<XxlJobGroup> findByAddressType(@Param("addressType") int addressType);
public int save(XxlJobGroup xxlJobGroup);
public int update(XxlJobGroup xxlJobGroup);
public int remove(@Param("id") int id);
public XxlJobGroup load(@Param("id") int id);
}
与mapper接口
对应的sql配置文件
在resource
资源路径下编写sql
语句
例如:namespace
命名空间一定要与mapper接口
一致
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobGroupDao">
<sql id="Base_Column_List">
t.id,
t.app_name,
t.title,
t.`order`,
t.address_type,
t.address_list
</sql>
<select id="findAll" resultMap="XxlJobGroup">
SELECT <include refid="Base_Column_List" />
FROM XXL_JOB_QRTZ_TRIGGER_GROUP AS t
ORDER BY t.order ASC
</select>
.
.
.
</mapper>
交由spring管理
由spring将mapper接口
与sql配置文件
关联起来
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:mybatis-mapper/*.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.xxl.job.admin.dao" />
</bean>
源码分析
SqlSessionFactoryBean
SqlSessionFactoryBean是一个FactoryBean,作用是注册Configuration
与解析sql配置
文件到Configuration中,并通过getObject()
返回SqlSessionFactory。
- 在后面会用该SqlSessionFactory对象创建
SqlSession
- 执行
sql
语句时会从Configuration中拿出sql配置信息
详解看mybatis与spring的整合之SqlSessionFactoryBean
MapperScannerConfigurer
实现了InitializingBean接口
MapperScannerConfigurer实现了接口InitializingBean,重写了afterPropertiesSet
方法
如果basePackage
没有注入值,则会报错
public void afterPropertiesSet() throws Exception {
notNull(this.basePackage, "Property 'basePackage' is required");
}
是工厂处理器
MapperScannerConfigurer是一个工厂处理器,实现了BeanDefinitionRegistryPostProcessor接口,重写了postProcessBeanDefinitionRegistry
方法,在执行工厂处理器时spring加载流程refresh之invokeBeanFactoryPostProcessors(beanFactory)会执行该方法:
构造ClassPathMapperScanner,用于扫描并注册
映射接口mybatis与spring的整合之ClassPathMapperScanner
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
if (this.processPropertyPlaceHolders) {
processPropertyPlaceHolders();
}
// 构造ClassPathMapperScanner,扫描注册映射接口
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.setAddToConfig(this.addToConfig);
scanner.setAnnotationClass(this.annotationClass);
scanner.setMarkerInterface(this.markerInterface);
scanner.setSqlSessionFactory(this.sqlSessionFactory);
scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
scanner.setResourceLoader(this.applicationContext);
scanner.setBeanNameGenerator(this.nameGenerator);
scanner.registerFilters();
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
注意:MapperScannerConfigurer中只有basePackage
是必须的,sqlSessionFactory
没有必要手动显示注入,spring会根据类型去寻找并注入