springboot动态修改mybatis的sql

@Service
public class TestServiceImpl {
    @Autowired
    org.apache.ibatis.session.SqlSessionFactory sessionFactory;
   
    /**
    *@author lixiao
    *@date 2023/4/27 10:38
    *@Description: 修改单个
    */
    public void test1(){
        try {
            Configuration configuration = sessionFactory.getConfiguration();
            //Mapper的全路径加方法名
            String id = "com.xxx.xx.XxxMapper.test";
            MappedStatement mappedStatement = configuration.getMappedStatement(id, false);
            RawSqlSource sqlSource = (RawSqlSource)mappedStatement.getSqlSource();
            Field sqlSource1 = sqlSource.getClass().getDeclaredField("sqlSource");
            sqlSource1.setAccessible(true);
            Object o = sqlSource1.get(sqlSource);
            Field sql1 = o.getClass().getDeclaredField("sql");
            sql1.setAccessible(true);
            BoundSql boundSql = sqlSource.getBoundSql(mappedStatement);
            String sql = boundSql.getSql();
            String newSql = sql.replace("cn", "en");
            sql1.set(o,newSql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
    *@author lixiao
    *@date 2023/4/27 10:37
    *@Description: 修改多个
    */
    public void test(){
        Configuration configuration = sessionFactory.getConfiguration();
        Collection<MappedStatement> mappedStatements = configuration.getMappedStatements();
        Field[] declaredFields = this.getClass().getDeclaredFields();
        List<String> strings = new ArrayList<>();
        //这个时筛选要修改哪些sql做准备的,
        for (Field declaredField : declaredFields) {
            strings.add(declaredField.getType().getName());
        }
        //循环mappedStatements,修改里面的sql
        for (Object mappedStatement1 : mappedStatements) {
            try {
                MappedStatement mappedStatement = null;

                mappedStatement = (MappedStatement) mappedStatement1;

                if (mappedStatement == null) {
                    continue;
                }
                if (!strings.contains(mappedStatement.getId().substring(0,mappedStatement.getId().lastIndexOf(".")))) {
                    continue;
                }
                RawSqlSource sqlSource = (RawSqlSource)mappedStatement.getSqlSource();
                Field sqlSource1 = sqlSource.getClass().getDeclaredField("sqlSource");
                sqlSource1.setAccessible(true);
                Object o = sqlSource1.get(sqlSource);
                Field sql1 = o.getClass().getDeclaredField("sql");
                sql1.setAccessible(true);
                BoundSql boundSql = sqlSource.getBoundSql(mappedStatement);
                String sql = boundSql.getSql();
                String newSql = sql.replace("cn", "en");
                sql1.set(o,newSql);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
### 如何配置 Spring Boot 自动打印 MyBatis SQL 语句 为了使 Spring Boot 应用程序能够自动打印由 MyBatis 生成的 SQL 语句,可以通过多种方式进行设置。以下是几种常见方法: #### 方法一:通过 `application.yml` 文件配置 可以在项目的 `application.yml` 或者 `application.properties` 中添加特定于 MyBatis 的属性来启用 SQL 日志记录功能。 对于 YAML 格式的配置文件,可以这样写入: ```yaml mybatis: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` 此配置项会指示 MyBatis 使用标准输出流作为日志实现工具[^2]。 #### 方法二:修改 MyBatis XML 配置文件中的 `<settings>` 节点 如果项目中有单独定义的 MyBatis XML 配置文件,则可在该文件内加入如下片段以激活 SQL 打印功能: ```xml <configuration> <settings> <!-- 启用SQL日志 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> </configuration> ``` 这种方式同样能有效触发 SQL 查询的日志输出至控制台[^4]。 #### 方法三:利用内置的日志框架进行更灵活的日志管理 考虑到实际生产环境中可能需要更加精细地控制日志级别以及目的地等因素,推荐采用基于现有 Java 日志库(如 Logback、Log4j 等)的方式来处理这个问题。例如,在使用 SLF4J 和 Logback 组合的情况下,只需调整相应的 logger 设置即可满足需求: ```properties logging.level.com.example.mapper=DEBUG ``` 这里假设所有的 Mapper 接口都位于包路径 `com.example.mapper` 下面;将这些接口的日志等级设为 DEBUG 就可以让它们发出详细的执行信息,包括完整的 SQL 文本[^5]。 以上三种方案均可达成目的,具体选用哪一种取决于个人偏好和技术栈的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值