MyBatis-Plus - 一篇带你解决自定义 SQL 注入器失效必杀技

简介: MyBatis-Plus - 一篇带你解决自定义 SQL 注入器失效必杀技

问题分析

Invalid bound statement (not found)


如果你看到这一篇,说明你也是遇到这个问题的人(废话),我们在上一篇(MyBatis-Plus - 一篇带你玩转自定义 BaseMapper)讲解过程当中,会发现最后用的是 @Component 注解进入注入到 Spring 容器,或者说有的地方采用 @Bean 的方式进行注入(半斤八两),但奇怪的是始种没生效,因为…


import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * @author Lux Sun
 * @date 2022/1/14
 */
@Component
public class DSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        methodList.add(new DeletePhysically());
        return methodList;
    }
}


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfiguration {
  @Bean
  public DSqlInjector sqlInjector() {
    return new DSqlInjector();
  }
}

解决方案

因为啥?如果在你没有犯了一些基础的错误情况下(比如:注解包没扫到啥啥啥的),那么你很有可能是因为使用自定义SqlSessionFactory,不会初始化刚开始自定义的 SQL 注入器了,知道这个基本问题就解决了,把集成项目的 SqlSessionFactory 去掉,或者加上 GlobalConfig 初始化这一块的代码“globalConfig.setSqlInjector(new DSqlInjector());”。


@Bean
@DependsOn({"springCtxUtil"})
public MybatisSqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
    MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
    // basic config
    String logicNotDeleteValue = "", logicDeleteValue = "", metaObjectHandler = "" , typeEnumsPackage = "",typeHandlersPackage = "";
    if (null != dynamicDataSourceProperties.getGlobalConfig()) {
        logicNotDeleteValue = dynamicDataSourceProperties.getGlobalConfig().getLogicNotDeleteValue();
        logicDeleteValue = dynamicDataSourceProperties.getGlobalConfig().getLogicDeleteValue();
        metaObjectHandler = dynamicDataSourceProperties.getGlobalConfig().getMetaObjectHandler();
        typeEnumsPackage= dynamicDataSourceProperties.getGlobalConfig().getTypeEnumsPackage();
        typeHandlersPackage= dynamicDataSourceProperties.getGlobalConfig().getTypeHandlersPackage();
    }
    MybatisConfiguration configuration = new MybatisConfiguration();
    GlobalConfig globalConfig = GlobalConfigUtils.defaults();
    GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
    globalConfig.setDbConfig(dbConfig);
    //【看到了吗?我在这呢!】
    globalConfig.setSqlInjector(new DSqlInjector());
    if (!StringUtils.isEmpty(metaObjectHandler)) {
        MetaObjectHandler metaObjectHandlerBean = (MetaObjectHandler) Class.forName(metaObjectHandler).newInstance();
        globalConfig.setMetaObjectHandler(metaObjectHandlerBean);
    }
    if (!StringUtils.isEmpty(logicDeleteValue)) {
        dbConfig.setLogicDeleteValue(logicDeleteValue);
    }
    if (!StringUtils.isEmpty(logicNotDeleteValue)) {
        dbConfig.setLogicNotDeleteValue(logicNotDeleteValue);
    }
    if (null != dynamicDataSourceProperties.getGlobalConfig() && null != dynamicDataSourceProperties.getGlobalConfig().getDefaultEnumTypeHandler()){
        configuration.setDefaultEnumTypeHandler(dynamicDataSourceProperties.getGlobalConfig().getDefaultEnumTypeHandler());
    }
    if (!StringUtils.isEmpty(typeEnumsPackage)){
        sqlSessionFactory.setTypeEnumsPackage(typeEnumsPackage);
    }
    if (!StringUtils.isEmpty(typeHandlersPackage)){
        sqlSessionFactory.setTypeHandlersPackage(typeHandlersPackage);
    }
    configuration.setCacheEnabled(false);
    sqlSessionFactory.setConfiguration(configuration);
    sqlSessionFactory.setGlobalConfig(globalConfig);
    // 使分页插件生效
    PaginationInterceptor paginationInterceptor = (PaginationInterceptor) SpringCtxUtil.getBean("paginationInterceptor");
    if (null != paginationInterceptor) {
        sqlSessionFactory.setPlugins(new Interceptor[]{paginationInterceptor});
    }
    // 配置数据源,此处配置为关键配置,如果没有将 dynamicDataSource 作为数据源则不能实现切换
    sqlSessionFactory.setDataSource(dynamicDataSource());
    // 扫描Model
    String typeAliasesPackage = dynamicDataSourceProperties.getTypeAliasesPackage();
    if (!StringUtils.isEmpty(typeAliasesPackage)) {
        sqlSessionFactory.setTypeAliasesPackage(typeAliasesPackage);
    }
    // 扫描映射文件
    String mapperLocations = dynamicDataSourceProperties.getMapperLocations();
    if (!StringUtils.isEmpty(mapperLocations)) {
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
    }
    return sqlSessionFactory;
}
目录
相关文章
|
2天前
|
SQL XML Java
mybatis实现动态sql
MyBatis的动态SQL功能为开发人员提供了强大的工具来应对复杂的查询需求。通过使用 `<if>`、`<choose>`、`<foreach>`等标签,可以根据不同的条件动态生成SQL语句,从而提高代码的灵活性和可维护性。本文详细介绍了动态SQL的基本用法和实际应用示例,希望对您在实际项目中使用MyBatis有所帮助。
23 11
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
29天前
|
SQL 安全 前端开发
Web学习_SQL注入_联合查询注入
联合查询注入是一种强大的SQL注入攻击方式,攻击者可以通过 `UNION`语句合并多个查询的结果,从而获取敏感信息。防御SQL注入需要多层次的措施,包括使用预处理语句和参数化查询、输入验证和过滤、最小权限原则、隐藏错误信息以及使用Web应用防火墙。通过这些措施,可以有效地提高Web应用程序的安全性,防止SQL注入攻击。
52 2
|
2月前
|
SQL 数据库 开发者
功能发布-自定义SQL查询
本期主要为大家介绍ClkLog九月上线的新功能-自定义SQL查询。
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
51 10
|
3月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
3月前
|
SQL 安全 数据库
惊!Python Web安全黑洞大曝光:SQL注入、XSS、CSRF,你中招了吗?
在数字化时代,Web应用的安全性至关重要。许多Python开发者在追求功能时,常忽视SQL注入、XSS和CSRF等安全威胁。本文将深入剖析这些风险并提供最佳实践:使用参数化查询预防SQL注入;通过HTML转义阻止XSS攻击;在表单中加入CSRF令牌增强安全性。遵循这些方法,可有效提升Web应用的安全防护水平,保护用户数据与隐私。安全需持续关注与改进,每个细节都至关重要。
142 5
|
3月前
|
SQL 安全 数据安全/隐私保护
Python Web安全大挑战:面对SQL注入、XSS、CSRF,你准备好了吗?
在构建Python Web应用时,安全性至关重要。本文通过三个真实案例,探讨了如何防范SQL注入、XSS和CSRF攻击。首先,通过参数化查询替代字符串拼接,防止SQL注入;其次,利用HTML转义机制,避免XSS攻击;最后,采用CSRF令牌验证,保护用户免受CSRF攻击。这些策略能显著增强应用的安全性,帮助开发者应对复杂的网络威胁。安全是一个持续的过程,需不断学习新知识以抵御不断变化的威胁。
127 1
|
2月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
145 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
73 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块