600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 记一次mybatis-plus自定义sql注入器不起作用的问题

记一次mybatis-plus自定义sql注入器不起作用的问题

时间:2022-01-10 20:34:37

相关推荐

记一次mybatis-plus自定义sql注入器不起作用的问题

之前自己写过一个关于mybatis-plus多表联查的组件,原理是用到了mybatis-plus扩展的口(sql注入),即继承DefaultSqlInjector

/**

@author chengang

*/

@Component

public class MySqlInjector extends DefaultSqlInjector {

@Override

public List getMethodList(Class<?> mapperClass) {

List methodList = super.getMethodList(mapperClass);

methodList.add(new JoinMethod());

return methodList;

}

}

但是集成到别的项目发现不起作用,很奇怪,batis-plus自带的查询没问题,但就是自定义注入器不行,不应该是初始化的时候从spring容器找吗。。。?

于是通过断点跟踪,发现注入器是GlobalConfig 的属性,并且有一个默认值

/**

SQL注入器

*/

private ISqlInjector sqlInjector = new DefaultSqlInjector();

显然之前肯定赋值过一次,继续往前追踪starter有个MybatisPlusAutoConfiguration里面有个初始化bean

@SuppressWarnings(“SpringJavaInjectionPointsAutowiringInspection”)

@Bean

@ConditionalOnMissingBean

public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {

// TODO 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBean

MybatisSqlSessionFactoryBean 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);

}

Resource[] mapperLocations = this.properties.resolveMapperLocations();

if (!ObjectUtils.isEmpty(mapperLocations)) {

factory.setMapperLocations(mapperLocations);

}

// TODO 修改源码支持定义 TransactionFactory

this.getBeanThen(TransactionFactory.class, factory::setTransactionFactory);

// TODO 对源码做了一定的修改(因为源码适配了老旧的mybatis版本,但我们不需要适配)Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();if (!ObjectUtils.isEmpty(this.languageDrivers)) {factory.setScriptingLanguageDrivers(this.languageDrivers);}Optional.ofNullable(defaultLanguageDriver).ifPresent(factory::setDefaultScriptingLanguageDriver);// TODO 自定义枚举包if (StringUtils.hasLength(this.properties.getTypeEnumsPackage())) {factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage());}// TODO 此处必为非 NULLGlobalConfig globalConfig = this.properties.getGlobalConfig();//这里是初始化全局缓存的最初开始// TODO 注入填充器this.getBeanThen(MetaObjectHandler.class, globalConfig::setMetaObjectHandler);// TODO 注入主键生成器this.getBeanThen(IKeyGenerator.class, i -> globalConfig.getDbConfig().setKeyGenerator(i));//这里注入自定义的主键生成器// TODO 注入sql注入器this.getBeanThen(ISqlInjector.class, globalConfig::setSqlInjector);//这里设置注入器属性,注入自定义注入器就在这里// TODO 注入ID生成器this.getBeanThen(IdentifierGenerator.class, globalConfig::setIdentifierGenerator);// TODO 设置 GlobalConfig 到 MybatisSqlSessionFactoryBeanfactory.setGlobalConfig(globalConfig);return factory.getObject();

}

到这里基本就很明确了,当你使用自定义SqlSessionFactory 的时候,本方法不会执行,也就不会初始化刚开始自定义的sql注入器了,知道这个基本问题就解决了,把集成项目的SqlSessionFactory 去掉,或者加上GlobalConfig初始化这一块的代码。

最后总结一下集成项目的时候一些bean的初始化要注意一些属性的初始化,不然可能会造成一些未知的问题!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。