Mybatis 拦截器--动态修改SQL

一、需求

表结构里面有两个固定字段,DATA_STATE 和 DELETE_MARKER

char(1) DATA_STATE 数据状态 (1正常 0逻辑删除)

char(1) DELETE_MARKER 删除标记 (0: 未删除,null:删除)

逻辑删除 DATA_STATE='0' 时,需要强制对对应的表字段(DELETE_MARKER)进行置空,

设置DELETE_MARKER=null。

二、方案

由于 DELETE_MARKER 字段是为了优化索引才加入表结构。系统中大量SQL语句,逻辑删除时,都只有 set data_state = '0',如果一个个修改,费事费力。

所以使用 Mybatis 拦截器来做,在SQL预编译的时候,拦截UPDATE类型SQL,判断是否 set data_state = '0' 如果是,修改SQL语句同步更新 delete_marker = null。

三、代码

package com.macrosoft.interceptor;

import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.scripting.xmltags.OgnlCache;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * DELETE_MARKER mybatis拦截器
 * 需求:
 *   DATA_STATE 数据状态 (1正常 0逻辑删除)
 *   DELETE_MARKER 删除标记 (0: 未删除,null:删除)
 *   逻辑删除 DATA_STATE=0时,需要强制对对应的表字段(DELETE_MARKER)进行置空,
 *   设置DELETE_MARKER=null
 * 拦截UPDATE类型SQL,判断是否 update data_state=0
 * 修改SQL语句同步更新delete_marker=null
 * @Author : linzp
 */
@Slf4j
@Component
@ConditionalOnProperty(prefix = "delete_marker_intercept", value = "enable", havingValue = "true")
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class })})
public class DeleteMarkerInterceptor implements Interceptor {

    private static final String LOGICAL_DELETION_STRING_VALUE = "0";

    private static final String DATA_STATE_PROPERTY = "dataState";

    private static final String DATA_STATE_FIELD_UPPERCASE = "DATA_STATE";

    private static final String DATA_ST
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值