首页 > 其他分享 >MyBatis修改操作注入动态全局参数

MyBatis修改操作注入动态全局参数

时间:2022-12-29 15:14:15浏览次数:36  
标签:parameterMappings propertyName value parameterMapping 参数 import MyBatis boundSql

有时候我们在更新字段的时候可能只更新一个状态,但是又需要记录当前的更新人和更新时间,比如:

updateStatus(@Param("id") String id, @Param("status") Integer status);

这个时候又不想创建DO或者DTO,可以添加一个全局的参数注入,把当前用户信息和当前时间注入到当前执行的sql的上下文中

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ReflectUtil;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.plugin.*;

import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

@Intercepts({
        @Signature(type = StatementHandler.class, method = "parameterize", args = {Statement.class})
})
public class InjectGlobalParamInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        if(StatementHandler.class.isAssignableFrom(target.getClass())) {
            RoutingStatementHandler statementHandler = (RoutingStatementHandler) target;
            BoundSql boundSql = statementHandler.getBoundSql();
            BaseStatementHandler delegate = (BaseStatementHandler) ReflectUtil.getFieldValue(statementHandler, "delegate");
            MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
            SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
            if(SqlCommandType.INSERT == sqlCommandType || SqlCommandType.UPDATE == sqlCommandType || SqlCommandType.DELETE == sqlCommandType) {
                putParamsIfNecessary(boundSql);
            }
        }
        return invocation.proceed();
    }

    private void putParamsIfNecessary(BoundSql boundSql) {
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        if (parameterMappings != null) {
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                if (parameterMapping.getMode() != ParameterMode.OUT) {
                    String propertyName = parameterMapping.getProperty();
                    if (Arrays.asList("_G_NOW", "_NOW").contains(propertyName)) {
                        boundSql.setAdditionalParameter(propertyName, DateUtil.date().toString());
                    }
                    if (Arrays.asList("_G_UUID", "_UUID").contains(propertyName)) {
                        boundSql.setAdditionalParameter(propertyName, IdUtil.fastSimpleUUID());
                    }
                }
            }
        }
    }

    @Override
    public Object plugin(Object target) {
        if (target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        }
        return target;
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

参考源码位置:
Mybatis:

// DefaultParameterHandler
@Override
 public void setParameters(PreparedStatement ps) {
   ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
   List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
   if (parameterMappings != null) {
     for (int i = 0; i < parameterMappings.size(); i++) {
       ParameterMapping parameterMapping = parameterMappings.get(i);
       if (parameterMapping.getMode() != ParameterMode.OUT) {
         Object value;
         String propertyName = parameterMapping.getProperty();
         if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
           value = boundSql.getAdditionalParameter(propertyName);
         } else if (parameterObject == null) {
           value = null;
         } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
           value = parameterObject;
         } else {
           MetaObject metaObject = configuration.newMetaObject(parameterObject);
           value = metaObject.getValue(propertyName);
         }
         TypeHandler typeHandler = parameterMapping.getTypeHandler();
         JdbcType jdbcType = parameterMapping.getJdbcType();
         if (value == null && jdbcType == null) {
           jdbcType = configuration.getJdbcTypeForNull();
         }
         try {
           typeHandler.setParameter(ps, i + 1, value, jdbcType);
         } catch (TypeException | SQLException e) {
           throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
         }
       }
     }
   }
 }

Mybatis-Plus:

// MybatisParameterHandler
@Override
   @SuppressWarnings("unchecked")
   public void setParameters(PreparedStatement ps) {
       ErrorContext.instance().activity("setting parameters").object(this.mappedStatement.getParameterMap().getId());
       List<ParameterMapping> parameterMappings = this.boundSql.getParameterMappings();
       if (parameterMappings != null) {
           for (int i = 0; i < parameterMappings.size(); i++) {
               ParameterMapping parameterMapping = parameterMappings.get(i);
               if (parameterMapping.getMode() != ParameterMode.OUT) {
                   Object value;
                   String propertyName = parameterMapping.getProperty();
                   if (this.boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
                       value = this.boundSql.getAdditionalParameter(propertyName);
                   } else if (this.parameterObject == null) {
                       value = null;
                   } else if (this.typeHandlerRegistry.hasTypeHandler(this.parameterObject.getClass())) {
                       value = parameterObject;
                   } else {
                       MetaObject metaObject = this.configuration.newMetaObject(this.parameterObject);
                       value = metaObject.getValue(propertyName);
                   }
                   TypeHandler typeHandler = parameterMapping.getTypeHandler();
                   JdbcType jdbcType = parameterMapping.getJdbcType();
                   if (value == null && jdbcType == null) {
                       jdbcType = this.configuration.getJdbcTypeForNull();
                   }
                   try {
                       typeHandler.setParameter(ps, i + 1, value, jdbcType);
                   } catch (TypeException | SQLException e) {
                       throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
                   }
               }
           }
       }
   }

标签:parameterMappings,propertyName,value,parameterMapping,参数,import,MyBatis,boundSql
From: https://www.cnblogs.com/charles69/p/17012574.html

相关文章

  • allure报告中allure.title 如何去掉后方的参数化显示
    问题描述allure报告中allure.title会自动拼接上传的参数,如何参数很长,前端展示的样式会很丑,详情如下:解决办法在引入的allure_pytest中的listener.py文件的94行注释掉参数......
  • 第一个Mybatis程序示例 Mybatis简介(一)
    一步一步搭建Mybatis的使用示例,项目中可能只是编写接口与XML映射文件,本文根据官方文档从底层描述一个完整示例,并对Mybatis进行了一个简单的介绍,作为入门......
  • 随手记(五):js函数参数默认值+热更新失效问题+常见操作符
    1.js函数参数ES5写法如果函数在调用时未提供隐式参数,参数会默认设置为: undefinedfunctionmyFunction(x,y){y=y||0;}ES6写法functionmyFunction(x,......
  • MybatisPlus实现按年份动态操作表数据
    MybatisPlus实现按年份动态操作表数据 在mp的官方网站上最近的一次更新可以看到,其提供了动态表名插件:https://baomidou.com/pages/2a45ff/#dynamictablenameinnerinterce......
  • 全局描述符表GDT
    段描述符:为了安全性,为内存段添加一些额外安全属性。添加内存段类型属性来阻止用户程序破坏存储代码的内存区域。添加特权级属性区分用户程序与操作系统。为了限制程序......
  • mybatis关联映射(1对多、多对1)
     准备测试数据班级表SETFOREIGN_KEY_CHECKS=0;--------------------------------Tablestructureforclasses------------------------------DROPTABLEIF......
  • 通达信程序化交易测试(2)——参数优化
    本博文记录本人学习笔记,纯属自娱自乐,不可作为投资依据,投资有风险,请您三思而后行!1.参数优化设置  2.评测结果 ......
  • 爱上 Mybatis源码 (2019-08-11)
     第一次学习源码,自己很难吃透源码,也做不到直接撸源码,一句一句的解析。先学习一下别人的文章,吃透源码的流程,日后有能力了再逐句撸。 源码的乐趣就在于首先能明白为什么我......
  • 多参数要加注解
    多参数要加注解如果要两个参数查询就要给参数加注解方法参数 packagecom.woniuxy.dao; ​ importcom.woniuxy.entity.Student; importorg.apache.ibatis.anno......
  • 全局引入elementplus和icon
    import { createApp } from 'vue'import App from './App.vue'import router from './router'import store from './store'import ElementPlus from 'ele......