彻底搞清mybaties plus实现原理

讨论主题主要想搞清楚几个问题

  1. MyBatis plus是依赖了mybatis,他们之间的关系是什么?
  2. mybatis plus中“字段自动填充功能”实现源码,包括id自动生成的原理 。
  3. mybatis plus 基本的增删改查为什么不用写sql?以及sql注入器的原理 。
本篇文章需要理解mybaties的源码为基础,否则看本篇文章会吃力 。mybaties源码分析可以看我上一篇文章,如下 彻底看懂springboot mybaties源码流程
mybaties plus是依赖了mybaties,他们之间的关系是什么?mybatis plus是基于mybatis实现的,下面来具体看看他们直接的关系,以及是怎样依赖的?
首先看mybatis plus自动配置类中的核心方法sqlSessionFactory,如下:
MybatisPlusAutoConfiguration
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {// mybaties plus使用 MybatisSqlSessionFactoryBean ,mybaties使用SqlSessionFactoryBeanMybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setVfs(SpringBootVFS.class);if (StringUtils.hasText(this.properties.getConfigLocation())) {factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));}ApplyConfiguration(factory);if (this.properties.getConfigurationProperties() != null) {factory.setConfigurationProperties(this.properties.getConfigurationProperties());}if (!ObjectUtils.isEmpty(this.interceptors)) {factory.setPlugins(this.interceptors);}if (this.databaseIdProvider != null) {factory.setDatabaseIdProvider(this.databaseIdProvider);}if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());}if (this.properties.getTypeAliasesSuperType() != null) {factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());}if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());}if (!ObjectUtils.isEmpty(this.typeHandlers)) {factory.setTypeHandlers(this.typeHandlers);}if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {factory.setMapperLocations(this.properties.resolveMapperLocations());}this.getBeanThen(TransactionFactory.class, factory::setTransactionFactory);Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();if (!ObjectUtils.isEmpty(this.languageDrivers)) {factory.setScriptingLanguageDrivers(this.languageDrivers);}Optional.ofNullable(defaultLanguageDriver).ifPresent(factory::setDefaultScriptingLanguageDriver);// 提供了可定制MybatisSqlSessionFactoryBean的类,如果你想定制它,你可以自定定义SqlSessionFactoryBeanCustomizer类型的类 。applySqlSessionFactoryBeanCustomizers(factory);// mybaties plus定义的全局的配置类,供后续方便使用 。GlobalConfig globalConfig = this.properties.getGlobalConfig();// 从spring容器中获取定义的MetaObjectHandler类型的实例,并设置到globalConfig供后续使用,这个就是// 字段自动填充功能的类 。this.getBeanThen(MetaObjectHandler.class, globalConfig::setMetaObjectHandler);// 从spring容器中获取IKeyGenerator类型实例(主要是实现主键生成器),并设置到globalConfig供后续使用this.getBeansThen(IKeyGenerator.class, i -> globalConfig.getDbConfig().setKeyGenerators(i));// 从spring容器中获取ISqlInjector类型实例(Sql注入器),并设置到globalConfig供后续使用this.getBeanThen(ISqlInjector.class, globalConfig::setSqlInjector);//从spring容器中获取IdentifierGenerator类型实例(主要是实现ID生成器),并设置到globalConfig供后续使用this.getBeanThen(IdentifierGenerator.class, globalConfig::setIdentifierGenerator);// 设置 GlobalConfig 到 MybatisSqlSessionFactoryBeanfactory.setGlobalConfig(globalConfig);return factory.getObject();}可以看到mybatis plus使用
MybatisSqlSessionFactoryBean (mybaties中使用的是SqlSessionFactoryBean),然后针对mybatis plus进行了一系列的初始化操作,并把相关的实例都设置到了GlobalConfig中,这块是mybatis plus扩展的初始化位置 。
mybaties plus定制了mybaties很多核心类,总结如下:
mybaties plus
mybaties
功能描述
MybatisSqlSessionFactoryBean
SqlSessionFactoryBean
调用buildSqlSessionFactory创建SqlSessionFactory类
MybatisConfiguration
Configuration
用于描述 MyBatis 主配置文件信息,MyBatis 框架在启动时自动配置类中,会加载mapper配置文件,将配置信息转换为 Configuration 对象,然后把该对象传入给sqlSessionFactory供后续使用
MybatisMapperAnnotationBuilder
MapperAnnotationBuilder
解析Mapper方法中用注解方式定义的sql 。
MybatisMapperRegistry


推荐阅读