| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- package jnpf.database.plugins;
- import com.baomidou.mybatisplus.core.metadata.TableInfo;
- import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
- import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
- import com.baomidou.mybatisplus.core.toolkit.*;
- import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
- import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
- import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
- import com.baomidou.mybatisplus.extension.toolkit.PropertyMapper;
- import jnpf.database.util.LogicDeleteHelper;
- import jnpf.util.StringUtil;
- import io.swagger.v3.oas.annotations.media.Schema;
- import lombok.Data;
- import lombok.extern.slf4j.Slf4j;
- import net.sf.jsqlparser.JSQLParserException;
- import net.sf.jsqlparser.expression.*;
- import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
- import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
- import net.sf.jsqlparser.expression.operators.relational.*;
- import net.sf.jsqlparser.parser.CCJSqlParserUtil;
- import net.sf.jsqlparser.schema.Column;
- import net.sf.jsqlparser.schema.Table;
- import net.sf.jsqlparser.statement.Statement;
- import net.sf.jsqlparser.statement.delete.Delete;
- import net.sf.jsqlparser.statement.insert.Insert;
- import net.sf.jsqlparser.statement.select.*;
- import net.sf.jsqlparser.statement.update.Update;
- import net.sf.jsqlparser.statement.update.UpdateSet;
- import org.apache.ibatis.executor.Executor;
- import org.apache.ibatis.executor.statement.StatementHandler;
- import org.apache.ibatis.mapping.BoundSql;
- import org.apache.ibatis.mapping.MappedStatement;
- import org.apache.ibatis.mapping.SqlCommandType;
- import org.apache.ibatis.session.ResultHandler;
- import org.apache.ibatis.session.RowBounds;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * 逻辑删除插件
- * @author JNPF开发平台组
- * @user N
- * @copyright 引迈信息技术有限公司
- * @date 2022/10/14 10:29
- */
- @Data
- @Slf4j
- public class MyLogicDeleteInnerInterceptor extends TenantLineInnerInterceptor implements InnerInterceptor {
- private LogicDeleteHandler logicDeleteHandler;
- private static List<String> tableName = new ArrayList<>();
- public MyLogicDeleteInnerInterceptor() {
- MyLogicDeleteInnerInterceptor instance = this;
- super.setTenantLineHandler(new TenantLineHandler() {
- @Override
- public String getTenantIdColumn() {
- return logicDeleteHandler.getLogicDeleteColumn();
- }
- @Override
- public Expression getTenantId() {
- return logicDeleteHandler.getNotDeletedValue();
- }
- @Override
- public boolean ignoreTable(String tableName) {
- return instance.ignoreTable(tableName);
- }
- });
- }
- private boolean isRemoveLogic(){
- return LogicDeleteHelper.isIgnoreLogicDelete();
- }
- @Override
- public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
- //MybatisPlus自带方法不处理, 兼容Plus、PlusJoin 见MyDefaultSqlInjector
- if (InterceptorIgnoreHelper.willIgnoreOthersByKey(ms.getId(), MyDefaultSqlInjector.ignoreLogicPrefix)) return;
- //方法名包含ignorelogic不过滤
- if (ms.getId().endsWith(MyDefaultSqlInjector.ignoreLogicPrefix)) return;
- try {
- if(!isRemoveLogic()) {
- //添加逻辑删除
- if(boundSql.getSql().toLowerCase().contains(logicDeleteHandler.getLogicDeleteColumn().toLowerCase())){
- //包含逻辑删除字段不处理
- return;
- }
- }
- PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
- mpBs.sql(parserSingle(mpBs.sql(), null));
- } catch (Exception e){
- //特殊语句解析失败
- if(log.isDebugEnabled()){
- log.debug("语句解析失败", e);
- }
- }
- }
- @Override
- public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
- PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
- MappedStatement ms = mpSh.mappedStatement();
- //MybatisPlus自带方法不处理, 兼容Plus、PlusJoin 见MyDefaultSqlInjector
- if (InterceptorIgnoreHelper.willIgnoreOthersByKey(ms.getId(), MyDefaultSqlInjector.ignoreLogicPrefix)) {
- return;
- }
- //方法名包含ignorelogic不过滤
- if (ms.getId().endsWith(MyDefaultSqlInjector.ignoreLogicPrefix)) return;
- SqlCommandType sct = ms.getSqlCommandType();
- if (sct == SqlCommandType.INSERT || sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) {
- if(!isRemoveLogic()) {
- //添加逻辑删除
- if (mpSh.mPBoundSql().sql().toLowerCase().contains(logicDeleteHandler.getLogicDeleteColumn().toLowerCase())) {
- //包含逻辑删除字段不处理
- return;
- }
- }
- try {
- PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
- mpBs.sql(parserMulti(mpBs.sql(), null));
- } catch (Exception e){
- //特殊语句解析失败
- if(log.isDebugEnabled()){
- log.debug("语句解析失败", e);
- }
- }
- }
- }
- @Override
- protected String processParser(Statement statement, int index, String sql, Object obj) {
- if (logger.isDebugEnabled()) {
- logger.debug("SQL to parse, SQL: " + sql);
- }
- if (statement instanceof Insert) {
- this.processInsert((Insert) statement, index, sql, obj);
- } else if (statement instanceof Select) {
- this.processSelect((Select) statement, index, sql, obj);
- } else if (statement instanceof Update) {
- this.processUpdate((Update) statement, index, sql, obj);
- } else if (statement instanceof Delete) {
- if(isRemoveLogic()) {
- //忽略逻辑删除就直接执行删除
- this.processDelete((Delete) statement, index, sql, obj);
- }else{
- //把删除语句替换为修改语句
- statement = this.processDeleteToLogicDelete((Delete) statement, index, sql, obj);
- }
- }
- sql = statement.toString();
- if (logger.isDebugEnabled()) {
- logger.debug("parse the finished SQL: " + sql);
- }
- return sql;
- }
- /**
- * delete 语句处理
- */
- protected Statement processDeleteToLogicDelete(Delete delete, int index, String sql, Object obj) {
- if (super.getTenantLineHandler().ignoreTable(delete.getTable().getName())) {
- // 过滤退出执行
- return delete;
- }
- Update updateStatement = null;
- try {
- updateStatement = (Update) CCJSqlParserUtil.parse(logicDeleteHandler.getDeleteSql());
- } catch (JSQLParserException e) {
- throw new RuntimeException(e);
- }
- updateStatement.setTable(delete.getTable());
- updateStatement.setWhere(delete.getWhere());
- return updateStatement;
- }
- @Override
- public void setProperties(Properties properties) {
- PropertyMapper.newInstance(properties).whenNotBlank("logicDeleteHandler",
- ClassUtils::newInstance, this::setLogicDeleteHandler);
- }
- @Override
- public Expression buildTableExpression(Table table, Expression where, String whereSegment) {
- if(getTenantLineHandler().ignoreTable(table.getName())){
- return null;
- }
- return getLogicExpression(this.getAliasColumn(table), logicDeleteHandler.getNotDeletedValue());
- }
- /**
- * 逻辑字段别名设置
- * <p>F_DELETEMARK 或 tableAlias.F_DELETEMARK</p>
- *
- * @param table 表对象
- * @return 字段
- */
- @Override
- protected Column getAliasColumn(Table table) {
- StringBuilder column = new StringBuilder();
- // 为了兼容隐式内连接,没有别名时条件就需要加上表名
- if (table.getAlias() != null) {
- column.append(table.getAlias().getName());
- } else {
- column.append(table.getName());
- }
- column.append(StringPool.DOT).append(logicDeleteHandler.getLogicDeleteColumn());
- return new Column(column.toString());
- }
- protected Expression getLogicExpression(Expression column, Expression val){
- if("null".equalsIgnoreCase(val.toString())){
- IsNullExpression isNullExpression = new IsNullExpression();
- isNullExpression.setLeftExpression(column);
- isNullExpression.setNot(false);
- return isNullExpression;
- }else {
- return new EqualsTo(column, val);
- }
- }
- private boolean ignoreTable(String table){
- if(StringUtil.isEmpty(table) || logicDeleteHandler.ignoreTable(table)){
- return true;
- }
- TableInfo tableInfo = TableInfoHelper.getTableInfo(table);
- //无实体暂不执行, 非逻辑删除表不执行
- if(tableInfo != null){
- return !tableInfo.isWithLogicDelete();
- }
- return true;
- }
- // ------------ 移除逻辑删除, 操作全部数据 开始 ------------ //
- @Override
- protected Expression builderExpression(Expression currentExpression, List<Table> tables, String whereSegment) {
- if(isRemoveLogic()) {
- return removeCondition(currentExpression);
- }
- return super.builderExpression(currentExpression, tables, whereSegment);
- }
- @Override
- protected Expression andExpression(Table table, Expression where, String whereSegment) {
- if(isRemoveLogic()) {
- return removeCondition(where);
- }
- return super.andExpression(table, where, whereSegment);
- }
- /**
- * 移除SQL中的逻辑删除条件
- * @param expression
- * @return
- */
- private Expression removeCondition(Expression expression){
- if (expression != null) {
- String sql = expression.toString();
- if(sql.contains(logicDeleteHandler.getLogicDeleteColumn())){
- if (expression instanceof AndExpression || expression instanceof OrExpression) {
- BinaryExpression expression1 = (BinaryExpression) expression;
- expression1.setLeftExpression(removeCondition(expression1.getLeftExpression()));
- expression1.setRightExpression(removeCondition(expression1.getRightExpression()));
- }
- if (expression instanceof EqualsTo || expression instanceof NotEqualsTo || expression instanceof IsNullExpression) {
- return new EqualsTo(new LongValue(1), new LongValue(1));
- }
- }
- }
- return expression;
- }
- // ------------ 移除逻辑删除, 操作全部数据 结束 ------------ //
- }
|