wl_management/src/main/java/com/lz/config/DataScopeInterceptor.java
2020-12-28 11:47:26 +08:00

274 lines
10 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2018-2025, songfayuan All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the 霖梓控股 developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: songfayuan (1414798079@qq.com)
*/
package com.lz.config;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
import com.lz.common.utils.OrderUtil;
import com.lz.common.utils.ReflectionUtils;
import com.lz.common.utils.SpringContextUtils;
import com.lz.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.BindingException;
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.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.text.DateFormat;
import java.util.*;
/**
* @author songfayuan
* @date 2018/1/19
* 数据权限插件guns
*/
@Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class DataScopeInterceptor extends AbstractSqlParserHandler implements Interceptor {
public static final org.slf4j.Logger logger = LoggerFactory.getLogger(DataScopeInterceptor.class);
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
this.sqlParser(metaObject);
// 先判断是不是SELECT操作
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
String originalSql = boundSql.getSql();
Object parameterObject = boundSql.getParameterObject();
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
String mapperdId = getMapperId(mappedStatement);
String sqlCommandTypePre = "SELECT SQL = " + mapperdId + " ";
if(SqlCommandType.INSERT.equals(mappedStatement.getSqlCommandType())){
sqlCommandTypePre = "INSERT SQL = " + mapperdId + " ";
}else if (SqlCommandType.UPDATE.equals(mappedStatement.getSqlCommandType())){
sqlCommandTypePre = "UPDATE SQL = " + mapperdId + " ";
}
Configuration configuration = mappedStatement.getConfiguration();
if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) { //非select语句
if(SpringContextUtils.isSQLLogDebug()){
logger.info(sqlCommandTypePre + showSql(configuration, boundSql));
}
Object result = invocation.proceed();
return result ;
}
//查找参数中包含DataScope类型的参数
DataScope dataScope = findDataScopeObject(parameterObject);
if (dataScope == null) {
String sql = getContainsIsDeleteOriginalSql(originalSql);
if(SpringContextUtils.isSQLLogDebug()){
logger.info(sqlCommandTypePre + showSql(configuration, boundSql));
}
metaObject.setValue("delegate.boundSql.sql", sql);
Object result = invocation.proceed();
return result ;
} else {
String scopeName = dataScope.getScopeName();
List<Integer> deptIds = dataScope.getDeptIds();
if (StringUtil.isNotBlank(scopeName) && CollectionUtil.isNotEmpty(deptIds)) {
String join = CollectionUtil.join(deptIds, ",");
originalSql = "select * from (" + originalSql + ") temp_data_scope where temp_data_scope." + scopeName + " in (" + join + ")";
metaObject.setValue("delegate.boundSql.sql", originalSql);
}
if(SpringContextUtils.isSQLLogDebug()){
logger.info(sqlCommandTypePre + showSql(configuration, boundSql));
}
Object result=invocation.proceed();
return result;
}
}
// todo quyixiao 所有的sql查询加上is_delete=0,目前没有想到解决办法
public static String getContainsIsDeleteOriginalSql(String originalSql){
return originalSql;
}
private static String getParameterValue(Object obj) {
String value = null;
if (obj instanceof String) {
value = "'" + obj.toString() + "'";
} else if (obj instanceof Date) {
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
value = "'" + formatter.format(obj) + "'";
} else {
if (obj != null) {
value = obj.toString();
} else {
value = "''";
}
}
return value;
}
@SuppressWarnings("unused")
private static Object getParameterValue(String propertyName, Object obj) {
Object value = null;
try {
value = ReflectionUtils.getObjectFieldValue(obj, propertyName);
} catch (BindingException e2) {
return null;
}
return value;
}
/**
* 生成拦截对象的代理
*
* @param target 目标对象
* @return 代理对象
*/
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
}
return target;
}
/**
* mybatis配置的属性
*
* @param properties mybatis配置的属性
*/
@Override
public void setProperties(Properties properties) {
}
public static String getMapperId(MappedStatement mappedStatement) {
try {
String id = mappedStatement.getId();
if(id.contains(".")){
String ids []= id.split("\\.");
return ids[ids.length -2 ] +"."+ ids[ids.length -1 ];
}
return null;
} catch (Exception e) {
e.printStackTrace();
} finally {
}
return "";
}
public static void main(String[] args) {
}
/**
* 查找参数是否包括DataScope对象
*
* @param parameterObj 参数列表
* @return DataScope
*/
private DataScope findDataScopeObject(Object parameterObj) {
if (parameterObj instanceof DataScope) {
return (DataScope) parameterObj;
} else if (parameterObj instanceof Map) {
for (Object val : ((Map<?, ?>) parameterObj).values()) {
if (val instanceof DataScope) {
return (DataScope) val;
}
}
}
return null;
}
public static String showSql(Configuration configuration, BoundSql boundSql) {
try {
Map<String,String> listMap = new HashMap<>();
Object parameterObject = boundSql.getParameterObject();
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
if (parameterMappings.size() > 0 && parameterObject != null) {
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
String value = getParameterValue(parameterObject);
if (value.contains("?")) {
String key = OrderUtil.getUserPoolOrder("rn");
listMap.put(key,value);
value = key;
}
sql = sql.replaceFirst("\\?", value);
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
for (ParameterMapping parameterMapping : parameterMappings) {
String propertyName = parameterMapping.getProperty();
if (metaObject.hasGetter(propertyName)) {
Object obj = metaObject.getValue(propertyName);
String value = getParameterValue(obj);
if (value.contains("?")) {
String key = OrderUtil.getUserPoolOrder("rn");
listMap.put(key,value);
value = key;
}
sql = sql.replaceFirst("\\?", value);
} else if (boundSql.hasAdditionalParameter(propertyName)) {
Object obj = boundSql.getAdditionalParameter(propertyName);
String value = getParameterValue(obj);
if (value.contains("?")) {
String key = OrderUtil.getUserPoolOrder("rn");
listMap.put(key,value);
value = key;
}
sql = sql.replaceFirst("\\?", value);
}
}
}
}
if(!listMap.isEmpty()){
for (Map.Entry<String, String> m : listMap.entrySet()) {
sql = sql.replaceAll(m.getKey(),m.getValue());
}
}
return sql;
} catch (Exception e) {
log.error("showSql exception ", e);
}
return "";
}
}