MyBatis是可以说是目前最主流的Spring持久层框架了,本文主要探讨SpringBoot集成MyBatis的底层原理。完整代码可移步Github。
如何使用MyBatis#
一般情况下,我们在SpringBoot项目中应该如何集成MyBatis呢?
引入MyBatis依赖
Copy
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.2
配置数据源
在启动类上添加@MapperScan注解,传入需要扫描的dao层的包路径
在dao层中创建接口,在方法上传入对应的SQL语句,也可以使用Mapper.xml文件进行配置。例如:
Copy
public interface UserDao {
@Select(“insert into user xxx”)
void insert();
}
完成这些工作后,我们就可以调用new UserDao().insert()方法来实现对数据库的操作了。
那么问题来了,MyBatis是如何通过如此简单的配置完成完成与Spring的“无缝连接”和数据的持久化工作的呢?
Spring的BeanDefinition#
众所周知,Spring的一大特性是IoC,既控制反转。当我们将一个对象交给Spring管理之后,我们就不需要手动地通过new关键字去创建对象,只需要通过@Autowired或者@Resource自动注入即可。那么这个过程是如何实现的呢?
简单来说,Spring会通过一个被声明为bean的类信息生成一个beanDefinition(后面简称BD)对象,然后通过这个BD对象创建一个单例(不声明为prototype的情况下),存入单例池,需要时进行调用。
在创建beadDefinition时,Spring会调用一系列的后置处理器(postProcessor)对BD加以处理,我们也可以自定义后置处理器,对BD的属性进行修改,只需要实现BeanFactoryPostProcessor接口即可,例如:
Copy
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition userDaoBD = (GenericBeanDefinition)beanFactory.getBeanDefinition(“userDao”);
userDaoBD.setBeanClassName(“userDaoChanged”);
userDaoBD.setAbstract(false);
// more…
}
}
在这个postProcessor中,我们获取了UserDao的BD对象,并且将它的名字修改为"userDaoChanged",这样我们就可以通过调用ApplicationContext的getBean(“userDaochanged”)方法获取到原来的userDao的bean。
关于MyBatis#
现在我们知道了,当我们将一个类交给Spring管理时,Sprin