通用mybatis-plus查询封装(QueryGenerator)

结果如下图所示

java类代码分别如下

1

java 复制代码
package com.hdx.contractor.util.mybatis;

import com.hdx.contractor.common.user.SecurityUser;
import com.hdx.contractor.common.user.UserDetail;
import com.hdx.contractor.util.query.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod.ParamMap;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.Properties;

/**
 * mybatis拦截器,自动注入创建人、创建时间、修改人、修改时间
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 *
 */
@Slf4j
@Component
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class MybatisInterceptor implements Interceptor {



	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
		String sqlId = mappedStatement.getId();
		log.debug("------sqlId------" + sqlId);
		SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
		Object parameter = invocation.getArgs()[1];
		log.debug("------sqlCommandType------" + sqlCommandType);

		if (parameter == null) {
			return invocation.proceed();
		}
		if (SqlCommandType.INSERT == sqlCommandType) {
			UserDetail sysUser = this.getLoginUser();
			Field[] fields = oConvertUtils.getAllFields(parameter);
			for (Field field : fields) {
				log.debug("------field.name------" + field.getName());
				try {
					if ("createBy".equals(field.getName())) {
						field.setAccessible(true);
						Object localCreateBy = field.get(parameter);
						field.setAccessible(false);
						if (localCreateBy == null || "".equals(localCreateBy)) {
							if (sysUser != null) {
								// 登录人账号
								field.setAccessible(true);
								field.set(parameter, sysUser.getUsername());
								field.setAccessible(false);
							}
						}
					}
					if ("userId".equals(field.getName())) {
						field.setAccessible(true);
						Object localuserId = field.get(parameter);
						field.setAccessible(false);
						if (localuserId == null || "".equals(localuserId)) {
							if (sysUser != null) {
								// 登录人账号
								field.setAccessible(true);
								field.set(parameter, sysUser.getId());
								field.setAccessible(false);
							}
						}
					}
					// 注入创建时间
					if ("createTime".equals(field.getName())) {
						field.setAccessible(true);
						Object localCreateDate = field.get(parameter);
						field.setAccessible(false);
						if (localCreateDate == null || "".equals(localCreateDate)) {
							field.setAccessible(true);
							field.set(parameter, new Date());
							field.setAccessible(false);
						}
					}
					//注入部门编码
					if ("sysOrgCode".equals(field.getName())) {
						field.setAccessible(true);
						Object localSysOrgCode = field.get(parameter);
						field.setAccessible(false);
						if (localSysOrgCode == null || "".equals(localSysOrgCode)) {
							// 获取登录用户信息
							if (sysUser != null) {
								field.setAccessible(true);
								//field.set(parameter, sysUser.getOrgCode());
								field.setAccessible(false);
							}
						}
					}

				} catch (Exception e) {
				}
			}
		}
		if (SqlCommandType.UPDATE == sqlCommandType) {
			UserDetail sysUser = this.getLoginUser();
			Field[] fields = null;
			if (parameter instanceof ParamMap) {
				ParamMap<?> p = (ParamMap<?>) parameter;
				//update-begin-author:scott date:20190729 for:批量更新报错issues/IZA3Q--
                String et = "et";
				if (p.containsKey(et)) {
					parameter = p.get(et);
				} else {
					parameter = p.get("param1");
				}
				//update-end-author:scott date:20190729 for:批量更新报错issues/IZA3Q-

				//update-begin-author:scott date:20190729 for:更新指定字段时报错 issues/#516-
				if (parameter == null) {
					return invocation.proceed();
				}
				//update-end-author:scott date:20190729 for:更新指定字段时报错 issues/#516-

				fields = oConvertUtils.getAllFields(parameter);
			} else {
				fields = oConvertUtils.getAllFields(parameter);
			}

			for (Field field : fields) {
				log.debug("------field.name------" + field.getName());
				try {
					if ("updateBy".equals(field.getName())) {
						//获取登录用户信息
						if (sysUser != null) {
							// 登录账号
							field.setAccessible(true);
							field.set(parameter, sysUser.getUsername());
							field.setAccessible(false);
						}
					}
					if ("updateTime".equals(field.getName())) {
						field.setAccessible(true);
						field.set(parameter, new Date());
						field.setAccessible(false);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return invocation.proceed();
	}

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

	@Override
	public void setProperties(Properties properties) {
		// TODO Auto-generated method stub
	}

	//update-begin--Author:scott  Date:20191213 for:关于使用Quzrtz 开启线程任务, #465
    /**
     * 获取登录用户
     * @return
     */
	private UserDetail getLoginUser() {
		UserDetail sysUser = null;
		try {
			sysUser = SecurityUser.getUser();
		} catch (Exception e) {
			//e.printStackTrace();
			sysUser = null;
		}
		return sysUser;
	}
	//update-end--Author:scott  Date:20191213 for:关于使用Quzrtz 开启线程任务, #465

}

2

java 复制代码
package com.hdx.contractor.util.query;

/**
 * @Description: 通用常量
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
public interface CommonConstant {


    /**
     * 未知的
     */
    String UNKNOWN = "unknown";


    /**
     * String 类型的空值
     */
    String STRING_NULL = "null";

    /**
     * 字典翻译文本后缀
     */
    String DICT_TEXT_SUFFIX = "_dictText";


}

3

java 复制代码
package com.hdx.contractor.util.query;

import com.baomidou.mybatisplus.annotation.DbType;
import com.hdx.contractor.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;

/**
 * @Description: 通用工具
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
@Slf4j
public class CommonUtils {


    /**
     * 文件名 正则字符串
     * 文件名支持的字符串:字母数字中文.-_()() 除此之外的字符将被删除
     */
    private static String FILE_NAME_REGEX = "[^A-Za-z\\.\\(\\)\\-()\\_0-9\\u4e00-\\u9fa5]";




    /**
     * 当前系统数据库类型
     */
    private static String DB_TYPE = "";
    private static DbType dbTypeEnum = null;

    /**
     * 全局获取平台数据库类型(作废了)
     *
     * @return
     */
    @Deprecated
    public static String getDatabaseType() {
        if (oConvertUtils.isNotEmpty(DB_TYPE)) {
            return DB_TYPE;
        }
        DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
        try {
            return getDatabaseTypeByDataSource(dataSource);
        } catch (SQLException e) {
            //e.printStackTrace();
            log.warn(e.getMessage(), e);
            return "";
        }
    }


    /**
     * 获取数据库类型
     *
     * @param dataSource
     * @return
     * @throws SQLException
     */
    private static String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException {
        if ("".equals(DB_TYPE)) {
            Connection connection = dataSource.getConnection();
            try {
                DatabaseMetaData md = connection.getMetaData();
                String dbType = md.getDatabaseProductName().toUpperCase();
                String sqlserver = "SQL SERVER";
                if (dbType.indexOf(DataBaseConstant.DB_TYPE_MYSQL) >= 0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
                } else if (dbType.indexOf(DataBaseConstant.DB_TYPE_ORACLE) >= 0 || dbType.indexOf(DataBaseConstant.DB_TYPE_DM) >= 0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
                } else if (dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER) >= 0 || dbType.indexOf(sqlserver) >= 0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
                } else if (dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL) >= 0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
                } else if (dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB) >= 0) {
                    DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
                } else {
                    log.error("数据库类型:[" + dbType + "]不识别!");
                    //throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                connection.close();
            }
        }
        return DB_TYPE;

    }

}

4

java 复制代码
package com.hdx.contractor.util.query;

import com.hdx.contractor.util.SpringContextUtils;

import java.util.List;

/**
 * @ClassName: DataAutorUtils
 * @Description: 数据权限查询规则容器工具类
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 * 
 */
public class DataAutorUtils {
	
	public static final String MENU_DATA_AUTHOR_RULES = "MENU_DATA_AUTHOR_RULES";

	/**
	 * 获取请求对应的数据权限规则
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static synchronized List<SysPermissionDataRuleModel> loadDataSearchConditon() {
		return (List<SysPermissionDataRuleModel>) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULES);
				
	}

}

5

java 复制代码
package com.hdx.contractor.util.query;
/**
 * 数据库上下文常量
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
public interface DataBaseConstant {
	//*********数据库类型****************************************

    /**MYSQL数据库*/
	public static final String DB_TYPE_MYSQL = "MYSQL";

    /** ORACLE*/
	public static final String DB_TYPE_ORACLE = "ORACLE";

    /**达梦数据库*/
	public static final String DB_TYPE_DM = "DM";

    /**postgreSQL达梦数据库*/
	public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";

    /**sqlserver数据库*/
	public static final String DB_TYPE_SQLSERVER = "SQLSERVER";

    /**mariadb 数据库*/
	public static final String DB_TYPE_MARIADB = "MARIADB";

    /**DB2 数据库*/
	public static final String DB_TYPE_DB2 = "DB2";

    /**HSQL 数据库*/
	public static final String DB_TYPE_HSQL = "HSQL";

//	// 数据库类型,对应 database_type 字典
//	public static final String DB_TYPE_MYSQL_NUM = "1";
//	public static final String DB_TYPE_MYSQL7_NUM = "6";
//	public static final String DB_TYPE_ORACLE_NUM = "2";
//	public static final String DB_TYPE_SQLSERVER_NUM = "3";
//	public static final String DB_TYPE_POSTGRESQL_NUM = "4";
//	public static final String DB_TYPE_MARIADB_NUM = "5";

	//*********系统上下文变量****************************************
	/**
	 * 数据-所属机构编码
	 */
	public static final String SYS_ORG_CODE = "sysOrgCode";
	/**
	 * 数据-所属机构编码
	 */
	public static final String SYS_ORG_CODE_TABLE = "sys_org_code";
	/**
	 * 数据-所属机构编码
	 */
	public static final String SYS_MULTI_ORG_CODE = "sysMultiOrgCode";
	/**
	 * 数据-所属机构编码
	 */
	public static final String SYS_MULTI_ORG_CODE_TABLE = "sys_multi_org_code";
	/**
	 * 数据-系统用户编码(对应登录用户账号)
	 */
	public static final String SYS_USER_CODE = "sysUserCode";
	/**
	 * 数据-系统用户编码(对应登录用户账号)
	 */
	public static final String SYS_USER_CODE_TABLE = "sys_user_code";
	
	/**
	 * 登录用户真实姓名
	 */
	public static final String SYS_USER_NAME = "sysUserName";
	/**
	 * 登录用户真实姓名
	 */
	public static final String SYS_USER_NAME_TABLE = "sys_user_name";
	/**
	 * 系统日期"yyyy-MM-dd"
	 */
	public static final String SYS_DATE = "sysDate";
	/**
	 * 系统日期"yyyy-MM-dd"
	 */
	public static final String SYS_DATE_TABLE = "sys_date";
	/**
	 * 系统时间"yyyy-MM-dd HH:mm"
	 */
	public static final String SYS_TIME = "sysTime";
	/**
	 * 系统时间"yyyy-MM-dd HH:mm"
	 */
	public static final String SYS_TIME_TABLE = "sys_time";
	/**
	 * 数据-所属机构编码
	 */
	public static final String SYS_BASE_PATH = "sys_base_path";
	//*********系统上下文变量****************************************
	
	
	//*********系统建表标准字段****************************************
	/**
	 * 创建者登录名称
	 */
	public static final String CREATE_BY_TABLE = "create_by";
	/**
	 * 创建者登录名称
	 */
	public static final String CREATE_BY = "createBy";
	/**
	 * 创建日期时间
	 */
	public static final String CREATE_TIME_TABLE = "create_time";
	/**
	 * 创建日期时间
	 */
	public static final String CREATE_TIME = "createTime";
	/**
	 * 更新用户登录名称
	 */
	public static final String UPDATE_BY_TABLE = "update_by";
	/**
	 * 更新用户登录名称
	 */
	public static final String UPDATE_BY = "updateBy";
	/**
	 * 更新日期时间
	 */
	public static final String UPDATE_TIME = "updateTime";
	/**
	 * 更新日期时间
	 */
	public static final String UPDATE_TIME_TABLE = "update_time";
	
	/**
	 * 业务流程状态
	 */
	public static final String BPM_STATUS = "bpmStatus";
	/**
	 * 业务流程状态
	 */
	public static final String BPM_STATUS_TABLE = "bpm_status";
	//*********系统建表标准字段****************************************


	/**
	 * 租户ID 实体字段名
	 */
	String TENANT_ID = "tenantId";
	/**
	 * 租户ID 数据库字段名
	 */
	String TENANT_ID_TABLE = "tenant_id";

    /**
     * sql语句 where
     */
    String SQL_WHERE = "where";

    /**
     * sql语句 asc
     */
    String SQL_ASC = "asc";

    /**
     * sqlserver数据库,中间有空格
     */
    String DB_TYPE_SQL_SERVER_BLANK = "sql server";
}

6

java 复制代码
package com.hdx.contractor.util.query;

/**
 * 查询链接规则
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
public enum MatchTypeEnum {

    /**查询链接规则 AND*/
    AND("AND"),
    /**查询链接规则 OR*/
    OR("OR");

    private String value;

    MatchTypeEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public static MatchTypeEnum getByValue(Object value) {
        if (oConvertUtils.isEmpty(value)) {
            return null;
        }
        return getByValue(value.toString());
    }

    public static MatchTypeEnum getByValue(String value) {
        if (oConvertUtils.isEmpty(value)) {
            return null;
        }
        for (MatchTypeEnum val : values()) {
            if (val.getValue().toLowerCase().equals(value.toLowerCase())) {
                return val;
            }
        }
        return null;
    }
}

7

java 复制代码
package com.hdx.contractor.util.query;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.Date;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 *
 */
@Slf4j
public class oConvertUtils {
	public static boolean isEmpty(Object object) {
		if (object == null) {
			return (true);
		}
		if ("".equals(object)) {
			return (true);
		}
		if (CommonConstant.STRING_NULL.equals(object)) {
			return (true);
		}
		return (false);
	}
	
	public static boolean isNotEmpty(Object object) {
		if (object != null && !"".equals(object) && !object.equals(CommonConstant.STRING_NULL)) {
			return (true);
		}
		return (false);
	}

	public static String decode(String strIn, String sourceCode, String targetCode) {
		String temp = code2code(strIn, sourceCode, targetCode);
		return temp;
	}

	@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
    public static String StrToUTF(String strIn, String sourceCode, String targetCode) {
		strIn = "";
		try {
			strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return strIn;

	}

	private static String code2code(String strIn, String sourceCode, String targetCode) {
		String strOut = null;
		if (strIn == null || "".equals(strIn.trim())) {
			return strIn;
		}
		try {
			byte[] b = strIn.getBytes(sourceCode);
			for (int i = 0; i < b.length; i++) {
				System.out.print(b[i] + "  ");
			}
			strOut = new String(b, targetCode);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return strOut;
	}

	public static int getInt(String s, int defval) {
		if (s == null || s == "") {
			return (defval);
		}
		try {
			return (Integer.parseInt(s));
		} catch (NumberFormatException e) {
			return (defval);
		}
	}

	public static int getInt(String s) {
		if (s == null || s == "") {
			return 0;
		}
		try {
			return (Integer.parseInt(s));
		} catch (NumberFormatException e) {
			return 0;
		}
	}

	public static int getInt(String s, Integer df) {
		if (s == null || s == "") {
			return df;
		}
		try {
			return (Integer.parseInt(s));
		} catch (NumberFormatException e) {
			return 0;
		}
	}

	public static Integer[] getInts(String[] s) {
		if (s == null) {
			return null;
		}
		Integer[] integer = new Integer[s.length];
		for (int i = 0; i < s.length; i++) {
			integer[i] = Integer.parseInt(s[i]);
		}
		return integer;

	}

	public static double getDouble(String s, double defval) {
		if (s == null || s == "") {
			return (defval);
		}
		try {
			return (Double.parseDouble(s));
		} catch (NumberFormatException e) {
			return (defval);
		}
	}

	public static double getDou(Double s, double defval) {
		if (s == null) {
			return (defval);
		}
		return s;
	}

	/*public static Short getShort(String s) {
		if (StringUtil.isNotEmpty(s)) {
			return (Short.parseShort(s));
		} else {
			return null;
		}
	}*/

	public static int getInt(Object object, int defval) {
		if (isEmpty(object)) {
			return (defval);
		}
		try {
			return (Integer.parseInt(object.toString()));
		} catch (NumberFormatException e) {
			return (defval);
		}
	}
	
	public static Integer getInt(Object object) {
		if (isEmpty(object)) {
			return null;
		}
		try {
			return (Integer.parseInt(object.toString()));
		} catch (NumberFormatException e) {
			return null;
		}
	}

	public static int getInt(BigDecimal s, int defval) {
		if (s == null) {
			return (defval);
		}
		return s.intValue();
	}

	public static Integer[] getIntegerArry(String[] object) {
		int len = object.length;
		Integer[] result = new Integer[len];
		try {
			for (int i = 0; i < len; i++) {
				result[i] = new Integer(object[i].trim());
			}
			return result;
		} catch (NumberFormatException e) {
			return null;
		}
	}

	public static String getString(String s) {
		return (getString(s, ""));
	}

	
	public static String getString(Object object) {
		if (isEmpty(object)) {
			return "";
		}
		return (object.toString().trim());
	}

	public static String getString(int i) {
		return (String.valueOf(i));
	}

	public static String getString(float i) {
		return (String.valueOf(i));
	}

	public static String getString(String s, String defval) {
		if (isEmpty(s)) {
			return (defval);
		}
		return (s.trim());
	}

	public static String getString(Object s, String defval) {
		if (isEmpty(s)) {
			return (defval);
		}
		return (s.toString().trim());
	}

	public static long stringToLong(String str) {
		Long test = new Long(0);
		try {
			test = Long.valueOf(str);
		} catch (Exception e) {
		}
		return test.longValue();
	}

	/**
	 * 获取本机IP
	 */
	public static String getIp() {
		String ip = null;
		try {
			InetAddress address = InetAddress.getLocalHost();
			ip = address.getHostAddress();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return ip;
	}

	/**
	 * 判断一个类是否为基本数据类型。
	 * 
	 * @param clazz
	 *            要判断的类。
	 * @return true 表示为基本数据类型。
	 */
	private static boolean isBaseDataType(Class clazz) throws Exception {
		return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive());
	}

	/**
	 * @param request
	 *            IP
	 * @return IP Address
	 */
	public static String getIpAddrByRequest(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * @return 本机IP
	 * @throws SocketException
	 */
	public static String getRealIp() throws SocketException {
        // 本地IP,如果没有配置外网IP则返回它
		String localip = null;
        // 外网IP
		String netip = null;

		Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
		InetAddress ip = null;
        // 是否找到外网IP
		boolean finded = false;
		while (netInterfaces.hasMoreElements() && !finded) {
			NetworkInterface ni = netInterfaces.nextElement();
			Enumeration<InetAddress> address = ni.getInetAddresses();
			while (address.hasMoreElements()) {
				ip = address.nextElement();
                // 外网IP
				if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {
					netip = ip.getHostAddress();
					finded = true;
					break;
				} else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {
                    // 内网IP
				    localip = ip.getHostAddress();
				}
			}
		}

		if (netip != null && !"".equals(netip)) {
			return netip;
		} else {
			return localip;
		}
	}

	/**
	 * java去除字符串中的空格、回车、换行符、制表符
	 * 
	 * @param str
	 * @return
	 */
	public static String replaceBlank(String str) {
		String dest = "";
		if (str != null) {
		    String reg = "\\s*|\t|\r|\n";
			Pattern p = Pattern.compile(reg);
			Matcher m = p.matcher(str);
			dest = m.replaceAll("");
		}
		return dest;

	}

	/**
	 * 判断元素是否在数组内
	 * 
	 * @param substring
	 * @param source
	 * @return
	 */
	public static boolean isIn(String substring, String[] source) {
		if (source == null || source.length == 0) {
			return false;
		}
		for (int i = 0; i < source.length; i++) {
			String aSource = source[i];
			if (aSource.equals(substring)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取Map对象
	 */
	public static Map<Object, Object> getHashMap() {
		return new HashMap<>(5);
	}

	/**
	 * SET转换MAP
	 * 
	 * @param str
	 * @return
	 */
	public static Map<Object, Object> setToMap(Set<Object> setobj) {
		Map<Object, Object> map = getHashMap();
		for (Iterator iterator = setobj.iterator(); iterator.hasNext();) {
			Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) iterator.next();
			map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim());
		}
		return map;

	}

	public static boolean isInnerIp(String ipAddress) {
		boolean isInnerIp = false;
		long ipNum = getIpNum(ipAddress);
		/**
		 * 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址
		 **/
		long aBegin = getIpNum("10.0.0.0");
		long aEnd = getIpNum("10.255.255.255");
		long bBegin = getIpNum("172.16.0.0");
		long bEnd = getIpNum("172.31.255.255");
		long cBegin = getIpNum("192.168.0.0");
		long cEnd = getIpNum("192.168.255.255");
		String localIp = "127.0.0.1";
		isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || localIp.equals(ipAddress);
		return isInnerIp;
	}

	private static long getIpNum(String ipAddress) {
		String[] ip = ipAddress.split("\\.");
		long a = Integer.parseInt(ip[0]);
		long b = Integer.parseInt(ip[1]);
		long c = Integer.parseInt(ip[2]);
		long d = Integer.parseInt(ip[3]);

		long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
		return ipNum;
	}

	private static boolean isInner(long userIp, long begin, long end) {
		return (userIp >= begin) && (userIp <= end);
	}
	
	/**
	 * 将下划线大写方式命名的字符串转换为驼峰式。
	 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
	 * 例如:hello_world->helloWorld
	 * 
	 * @param name
	 *            转换前的下划线大写方式命名的字符串
	 * @return 转换后的驼峰式命名的字符串
	 */
	public static String camelName(String name) {
		StringBuilder result = new StringBuilder();
		// 快速检查
		if (name == null || name.isEmpty()) {
			// 没必要转换
			return "";
		} else if (!name.contains(SymbolConstant.UNDERLINE)) {
			// 不含下划线,仅将首字母小写
			//update-begin--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
			//update-begin--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
			return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase();
			//update-end--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
		}
		// 用下划线将原始字符串分割
		String[] camels = name.split("_");
		for (String camel : camels) {
			// 跳过原始字符串中开头、结尾的下换线或双重下划线
			if (camel.isEmpty()) {
				continue;
			}
			// 处理真正的驼峰片段
			if (result.length() == 0) {
				// 第一个驼峰片段,全部字母都小写
				result.append(camel.toLowerCase());
			} else {
				// 其他的驼峰片段,首字母大写
				result.append(camel.substring(0, 1).toUpperCase());
				result.append(camel.substring(1).toLowerCase());
			}
		}
		return result.toString();
	}
	
	/**
	 * 将下划线大写方式命名的字符串转换为驼峰式。
	 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
	 * 例如:hello_world,test_id->helloWorld,testId
	 * 
	 * @param name
	 *            转换前的下划线大写方式命名的字符串
	 * @return 转换后的驼峰式命名的字符串
	 */
	public static String camelNames(String names) {
		if(names==null||"".equals(names)){
			return null;
		}
		StringBuffer sf = new StringBuffer();
		String[] fs = names.split(",");
		for (String field : fs) {
			field = camelName(field);
			sf.append(field + ",");
		}
		String result = sf.toString();
		return result.substring(0, result.length() - 1);
	}
	
	//update-begin--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
	/**
	 * 将下划线大写方式命名的字符串转换为驼峰式。(首字母写)
	 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
	 * 例如:hello_world->HelloWorld
	 * 
	 * @param name
	 *            转换前的下划线大写方式命名的字符串
	 * @return 转换后的驼峰式命名的字符串
	 */
	public static String camelNameCapFirst(String name) {
		StringBuilder result = new StringBuilder();
		// 快速检查
		if (name == null || name.isEmpty()) {
			// 没必要转换
			return "";
		} else if (!name.contains(SymbolConstant.UNDERLINE)) {
			// 不含下划线,仅将首字母小写
			return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
		}
		// 用下划线将原始字符串分割
		String[] camels = name.split("_");
		for (String camel : camels) {
			// 跳过原始字符串中开头、结尾的下换线或双重下划线
			if (camel.isEmpty()) {
				continue;
			}
			// 其他的驼峰片段,首字母大写
			result.append(camel.substring(0, 1).toUpperCase());
			result.append(camel.substring(1).toLowerCase());
		}
		return result.toString();
	}
	//update-end--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
	
	/**
	 * 将驼峰命名转化成下划线
	 * @param para
	 * @return
	 */
	public static String camelToUnderline(String para){
	    int length = 3;
        if(para.length()<length){
        	return para.toLowerCase(); 
        }
        StringBuilder sb=new StringBuilder(para);
        //定位
        int temp=0;
        //从第三个字符开始 避免命名不规范 
        for(int i=2;i<para.length();i++){
            if(Character.isUpperCase(para.charAt(i))){
                sb.insert(i+temp, "_");
                temp+=1;
            }
        }
        return sb.toString().toLowerCase(); 
	}

	/**
	 * 随机数
	 * @param place 定义随机数的位数
	 */
	public static String randomGen(int place) {
		String base = "qwertyuioplkjhgfdsazxcvbnmQAZWSXEDCRFVTGBYHNUJMIKLOP0123456789";
		StringBuffer sb = new StringBuffer();
		Random rd = new Random();
		for(int i=0;i<place;i++) {
			sb.append(base.charAt(rd.nextInt(base.length())));
		}
		return sb.toString();
	}
	
	/**
	 * 获取类的所有属性,包括父类
	 * 
	 * @param object
	 * @return
	 */
	public static Field[] getAllFields(Object object) {
		Class<?> clazz = object.getClass();
		List<Field> fieldList = new ArrayList<>();
		while (clazz != null) {
			fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
			clazz = clazz.getSuperclass();
		}
		Field[] fields = new Field[fieldList.size()];
		fieldList.toArray(fields);
		return fields;
	}
	
	/**
	  * 将map的key全部转成小写
	 * @param list
	 * @return
	 */
	public static List<Map<String, Object>> toLowerCasePageList(List<Map<String, Object>> list){
		List<Map<String, Object>> select = new ArrayList<>();
		for (Map<String, Object> row : list) {
			 Map<String, Object> resultMap = new HashMap<>(5);
			 Set<String> keySet = row.keySet(); 
			 for (String key : keySet) { 
				 String newKey = key.toLowerCase(); 
				 resultMap.put(newKey, row.get(key)); 
			 }
			 select.add(resultMap);
		}
		return select;
	}

	/**
	 * 将entityList转换成modelList
	 * @param fromList
	 * @param tClass
	 * @param <F>
	 * @param <T>
	 * @return
	 */
	public static<F,T> List<T> entityListToModelList(List<F> fromList, Class<T> tClass){
		if(fromList == null || fromList.isEmpty()){
			return null;
		}
		List<T> tList = new ArrayList<>();
		for(F f : fromList){
			T t = entityToModel(f, tClass);
			tList.add(t);
		}
		return tList;
	}

	public static<F,T> T entityToModel(F entity, Class<T> modelClass) {
		log.debug("entityToModel : Entity属性的值赋值到Model");
		Object model = null;
		if (entity == null || modelClass ==null) {
			return null;
		}

		try {
			model = modelClass.newInstance();
		} catch (InstantiationException e) {
			log.error("entityToModel : 实例化异常", e);
		} catch (IllegalAccessException e) {
			log.error("entityToModel : 安全权限异常", e);
		}
		BeanUtils.copyProperties(entity, model);
		return (T)model;
	}

	/**
	 * 判断 list 是否为空
	 *
	 * @param list
	 * @return true or false
	 * list == null		: true
	 * list.size() == 0	: true
	 */
	public static boolean listIsEmpty(Collection list) {
		return (list == null || list.size() == 0);
	}

	/**
	 * 判断 list 是否不为空
	 *
	 * @param list
	 * @return true or false
	 * list == null		: false
	 * list.size() == 0	: false
	 */
	public static boolean listIsNotEmpty(Collection list) {
		return !listIsEmpty(list);
	}

}

8

java 复制代码
package com.hdx.contractor.util.query;

import java.io.Serializable;

/**
 * @Description: QueryCondition
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
public class QueryCondition implements Serializable {

	private static final long serialVersionUID = 4740166316629191651L;
	
	private String field;
	/** 组件的类型(例如:input、select、radio) */
	private String type;
	/**
	 * 对应的数据库字段的类型
	 * 支持:int、bigDecimal、short、long、float、double、boolean
	 */
	private String dbType;
	private String rule;
	private String val;
	
	public String getField() {
		return field;
	}

	public void setField(String field) {
		this.field = field;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getDbType() {
		return dbType;
	}

	public void setDbType(String dbType) {
		this.dbType = dbType;
	}

	public String getRule() {
		return rule;
	}

	public void setRule(String rule) {
		this.rule = rule;
	}

	public String getVal() {
		return val;
	}

	public void setVal(String val) {
		this.val = val;
	}

	@Override
	public String toString(){
		StringBuffer sb =new StringBuffer();
		if(field == null || "".equals(field)){
			return "";
		}
		sb.append(this.field).append(" ").append(this.rule).append(" ").append(this.type).append(" ").append(this.dbType).append(" ").append(this.val);
		return sb.toString();
	}
}

9

java 复制代码
package com.hdx.contractor.util.query;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.util.NumberUtils;

import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description: 查询生成器
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
@Slf4j
public class QueryGenerator {
    public static final String SQL_RULES_COLUMN = "SQL_RULES_COLUMN";

    private static final String BEGIN = "_begin";
    private static final String END = "_end";
    /**
     * 数字类型字段,拼接此后缀 接受多值参数
     */
    private static final String MULTI = "_MultiString";
    private static final String STAR = "*";
    private static final String COMMA = ",";
    /**
     * 查询 逗号转义符 相当于一个逗号【作废】
     */
    public static final String QUERY_COMMA_ESCAPE = "++";
    private static final String NOT_EQUAL = "!";
    /**
     * 页面带有规则值查询,空格作为分隔符
     */
    private static final String QUERY_SEPARATE_KEYWORD = " ";
    /**
     * 高级查询前端传来的参数名
     */
    private static final String SUPER_QUERY_PARAMS = "superQueryParams";
    /**
     * 高级查询前端传来的拼接方式参数名
     */
    private static final String SUPER_QUERY_MATCH_TYPE = "superQueryMatchType";
    /**
     * 单引号
     */
    public static final String SQL_SQ = "'";
    /**
     * 排序列
     */
    private static final String ORDER_COLUMN = "column";
    /**
     * 排序方式
     */
    private static final String ORDER_TYPE = "order";
    private static final String ORDER_TYPE_ASC = "ASC";

    /**
     * mysql 模糊查询之特殊字符下划线 (_、\)
     */
    public static final String LIKE_MYSQL_SPECIAL_STRS = "_,%";

    /**
     * 日期格式化yyyy-MM-dd
     */
    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    /**
     * to_date
     */
    public static final String TO_DATE = "to_date";

    /**
     * 时间格式化
     */
    private static final ThreadLocal<SimpleDateFormat> LOCAL = new ThreadLocal<SimpleDateFormat>();

    private static SimpleDateFormat getTime() {
        SimpleDateFormat time = LOCAL.get();
        if (time == null) {
            time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            LOCAL.set(time);
        }
        return time;
    }

    /**
     * 获取查询条件构造器QueryWrapper实例 通用查询条件已被封装完成
     *
     * @param searchObj    查询实体
     * @param parameterMap request.getParameterMap()
     * @return QueryWrapper实例
     */
    public static <T> QueryWrapper<T> initQueryWrapper(T searchObj, Map<String, String[]> parameterMap) {
        long start = System.currentTimeMillis();
        QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
        installMplus(queryWrapper, searchObj, parameterMap);
        log.debug("---查询条件构造器初始化完成,耗时:" + (System.currentTimeMillis() - start) + "毫秒----");
        return queryWrapper;
    }

    /**
     * 组装Mybatis Plus 查询条件
     * <p>使用此方法 需要有如下几点注意:
     * <br>1.使用QueryWrapper 而非LambdaQueryWrapper;
     * <br>2.实例化QueryWrapper时不可将实体传入参数
     * <br>错误示例:如QueryWrapper<JeecgDemo> queryWrapper = new QueryWrapper<JeecgDemo>(jeecgDemo);
     * <br>正确示例:QueryWrapper<JeecgDemo> queryWrapper = new QueryWrapper<JeecgDemo>();
     * <br>3.也可以不使用这个方法直接调用 {@link #initQueryWrapper}直接获取实例
     */
    private static void installMplus(QueryWrapper<?> queryWrapper, Object searchObj, Map<String, String[]> parameterMap) {
		
		/*
		 * 注意:权限查询由前端配置数据规则 当一个人有多个所属部门时候 可以在规则配置包含条件 orgCode 包含 #{sys_org_code}
		但是不支持在自定义SQL中写orgCode in #{sys_org_code} 
		当一个人只有一个部门 就直接配置等于条件: orgCode 等于 #{sys_org_code} 或者配置自定义SQL: orgCode = '#{sys_org_code}'
		*/

        //区间条件组装 模糊查询 高级查询组装 简单排序 权限查询
        PropertyDescriptor[] origDescriptors = PropertyUtils.getPropertyDescriptors(searchObj);
        Map<String, SysPermissionDataRuleModel> ruleMap = getRuleMap();

        //权限规则自定义SQL表达式
        for (String c : ruleMap.keySet()) {
            if (oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)) {
                queryWrapper.and(i -> i.apply(getSqlRuleValue(ruleMap.get(c).getRuleValue())));
            }
        }

        String name, type, column;
        // update-begin--Author:taoyan  Date:20200923 for:issues/1671 如果字段加注解了@TableField(exist = false),不走DB查询-------
        //定义实体字段和数据库字段名称的映射 高级查询中 只能获取实体字段 如果设置TableField注解 那么查询条件会出问题
        Map<String, String> fieldColumnMap = new HashMap<>(5);
        for (int i = 0; i < origDescriptors.length; i++) {
            //aliasName = origDescriptors[i].getName();  mybatis  不存在实体属性 不用处理别名的情况
            name = origDescriptors[i].getName();
            type = origDescriptors[i].getPropertyType().toString();
            try {
                if (judgedIsUselessField(name) || !PropertyUtils.isReadable(searchObj, name)) {
                    continue;
                }

                Object value = PropertyUtils.getSimpleProperty(searchObj, name);
                column = getTableFieldName(searchObj.getClass(), name);
                if (column == null) {
                    //column为null只有一种情况 那就是 添加了注解@TableField(exist = false) 后续都不用处理了
                    continue;
                }
                fieldColumnMap.put(name, column);
                //数据权限查询
                if (ruleMap.containsKey(name)) {
                    addRuleToQueryWrapper(ruleMap.get(name), column, origDescriptors[i].getPropertyType(), queryWrapper);
                }
                //区间查询
                doIntervalQuery(queryWrapper, parameterMap, type, name, column);
                //判断单值  参数带不同标识字符串 走不同的查询
                //TODO 这种前后带逗号的支持分割后模糊查询(多选字段查询生效) 示例:,1,3,
                if (null != value && value.toString().startsWith(COMMA) && value.toString().endsWith(COMMA)) {
                    String multiLikeval = value.toString().replace(",,", COMMA);
                    String[] vals = multiLikeval.substring(1, multiLikeval.length()).split(COMMA);
                    final String field = oConvertUtils.camelToUnderline(column);
                    if (vals.length > 1) {
                        queryWrapper.and(j -> {
                            log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}", field, "like", vals[0]);
                            j = j.like(field, vals[0]);
                            for (int k = 1; k < vals.length; k++) {
                                j = j.or().like(field, vals[k]);
                                log.info("---查询过滤器,Query规则 .or()---field:{}, rule:{}, value:{}", field, "like", vals[k]);
                            }
                            //return j;
                        });
                    } else {
                        log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}", field, "like", vals[0]);
                        queryWrapper.and(j -> j.like(field, vals[0]));
                    }
                } else {
                    //根据参数值带什么关键字符串判断走什么类型的查询
                    QueryRuleEnum rule = convert2Rule(value);
                    value = replaceValue(rule, value);
                    // add -begin 添加判断为字符串时设为全模糊查询
                    //if( (rule==null || QueryRuleEnum.EQ.equals(rule)) && "class java.lang.String".equals(type)) {
                    // 可以设置左右模糊或全模糊,因人而异
                    //rule = QueryRuleEnum.LIKE;
                    //}
                    // add -end 添加判断为字符串时设为全模糊查询
                    addEasyQuery(queryWrapper, column, rule, value);
                }

            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        // 排序逻辑 处理
        doMultiFieldsOrder(queryWrapper, parameterMap, fieldColumnMap);

        //高级查询
        doSuperQuery(queryWrapper, parameterMap, fieldColumnMap);
        // update-end--Author:taoyan  Date:20200923 for:issues/1671 如果字段加注解了@TableField(exist = false),不走DB查询-------

    }


    /**
     * 区间查询
     *
     * @param queryWrapper query对象
     * @param parameterMap 参数map
     * @param type         字段类型
     * @param filedName    字段名称
     * @param columnName   列名称
     */
    private static void doIntervalQuery(QueryWrapper<?> queryWrapper, Map<String, String[]> parameterMap, String type, String filedName, String columnName) throws ParseException {
        // 添加 判断是否有区间值
        String endValue = null, beginValue = null;
        if (parameterMap != null && parameterMap.containsKey(filedName + BEGIN)) {
            beginValue = parameterMap.get(filedName + BEGIN)[0].trim();
            addQueryByRule(queryWrapper, columnName, type, beginValue, QueryRuleEnum.GE);

        }
        if (parameterMap != null && parameterMap.containsKey(filedName + END)) {
            endValue = parameterMap.get(filedName + END)[0].trim();
            addQueryByRule(queryWrapper, columnName, type, endValue, QueryRuleEnum.LE);
        }
        //多值查询
        if (parameterMap != null && parameterMap.containsKey(filedName + MULTI)) {
            endValue = parameterMap.get(filedName + MULTI)[0].trim();
            addQueryByRule(queryWrapper, columnName.replace(MULTI, ""), type, endValue, QueryRuleEnum.IN);
        }
    }

    private static void doMultiFieldsOrder(QueryWrapper<?> queryWrapper, Map<String, String[]> parameterMap, Map<String, String> fieldColumnMap) {
        Set<String> allFields = fieldColumnMap.keySet();
        String column = null, order = null;
        if (parameterMap != null && parameterMap.containsKey(ORDER_COLUMN)) {
            column = parameterMap.get(ORDER_COLUMN)[0];
        }
        if (parameterMap != null && parameterMap.containsKey(ORDER_TYPE)) {
            order = parameterMap.get(ORDER_TYPE)[0];
        }
        log.info("排序规则>>列:" + column + ",排序方式:" + order);

        //update-begin-author:scott date:2022-11-07 for:避免用户自定义表无默认字段{创建时间},导致排序报错
        //TODO 避免用户自定义表无默认字段创建时间,导致排序报错
        if (DataBaseConstant.CREATE_TIME.equals(column) && !fieldColumnMap.containsKey(DataBaseConstant.CREATE_TIME)) {
            column = "id";
            log.warn("检测到实体里没有字段createTime,改成采用ID排序!");
        }
        //update-end-author:scott date:2022-11-07 for:避免用户自定义表无默认字段{创建时间},导致排序报错

        if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
            //字典字段,去掉字典翻译文本后缀
            if (column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
                column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
            }

            //update-begin-author:taoyan date:2022-5-16 for: issues/3676 获取系统用户列表时,使用SQL注入生效
            //判断column是不是当前实体的
            log.debug("当前字段有:" + allFields);
            if (!allColumnExist(column, allFields)) {
                throw new RuntimeException("请注意,将要排序的列字段不存在:" + column);
            }
            //update-end-author:taoyan date:2022-5-16 for: issues/3676 获取系统用户列表时,使用SQL注入生效

            //update-begin-author:scott date:2022-10-10 for:【jeecg-boot/issues/I5FJU6】doMultiFieldsOrder() 多字段排序方法存在问题
            //多字段排序方法没有读取 MybatisPlus 注解 @TableField 里 value 的值
            if (column.contains(",")) {
                List<String> columnList = Arrays.asList(column.split(","));
                String columnStrNew = columnList.stream().map(c -> fieldColumnMap.get(c)).collect(Collectors.joining(","));
                if (oConvertUtils.isNotEmpty(columnStrNew)) {
                    column = columnStrNew;
                }
            } else {
                column = fieldColumnMap.get(column);
            }
            //update-end-author:scott date:2022-10-10 for:【jeecg-boot/issues/I5FJU6】doMultiFieldsOrder() 多字段排序方法存在问题

            //SQL注入check
            SqlInjectionUtil.filterContent(column);

            //update-begin--Author:scott  Date:20210531 for:36 多条件排序无效问题修正-------
            // 排序规则修改
            // 将现有排序 _ 前端传递排序条件{....,column: 'column1,column2',order: 'desc'} 翻译成sql "column1,column2 desc"
            // 修改为 _ 前端传递排序条件{....,column: 'column1,column2',order: 'desc'} 翻译成sql "column1 desc,column2 desc"
            if (order.toUpperCase().indexOf(ORDER_TYPE_ASC) >= 0) {
                //queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
                String columnStr = oConvertUtils.camelToUnderline(column);
                String[] columnArray = columnStr.split(",");
                queryWrapper.orderByAsc(Arrays.asList(columnArray));
            } else {
                //queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
                String columnStr = oConvertUtils.camelToUnderline(column);
                String[] columnArray = columnStr.split(",");
                queryWrapper.orderByDesc(Arrays.asList(columnArray));
            }
            //update-end--Author:scott  Date:20210531 for:36 多条件排序无效问题修正-------
        }
    }

    //update-begin-author:taoyan date:2022-5-23 for: issues/3676 获取系统用户列表时,使用SQL注入生效

    /**
     * 多字段排序 判断所传字段是否存在
     *
     * @return
     */
    private static boolean allColumnExist(String columnStr, Set<String> allFields) {
        boolean exist = true;
        if (columnStr.indexOf(COMMA) >= 0) {
            String[] arr = columnStr.split(COMMA);
            for (String column : arr) {
                if (!allFields.contains(column)) {
                    exist = false;
                    break;
                }
            }
        } else {
            exist = allFields.contains(columnStr);
        }
        return exist;
    }
    //update-end-author:taoyan date:2022-5-23 for: issues/3676 获取系统用户列表时,使用SQL注入生效

    /**
     * 高级查询
     *
     * @param queryWrapper   查询对象
     * @param parameterMap   参数对象
     * @param fieldColumnMap 实体字段和数据库列对应的map
     */
    private static void doSuperQuery(QueryWrapper<?> queryWrapper, Map<String, String[]> parameterMap, Map<String, String> fieldColumnMap) {
        if (parameterMap != null && parameterMap.containsKey(SUPER_QUERY_PARAMS)) {
            String superQueryParams = parameterMap.get(SUPER_QUERY_PARAMS)[0];
            String superQueryMatchType = parameterMap.get(SUPER_QUERY_MATCH_TYPE) != null ? parameterMap.get(SUPER_QUERY_MATCH_TYPE)[0] : MatchTypeEnum.AND.getValue();
            MatchTypeEnum matchType = MatchTypeEnum.getByValue(superQueryMatchType);
            // update-begin--Author:sunjianlei  Date:20200325 for:高级查询的条件要用括号括起来,防止和用户的其他条件冲突 -------
            try {
                superQueryParams = URLDecoder.decode(superQueryParams, "UTF-8");
                List<QueryCondition> conditions = JSON.parseArray(superQueryParams, QueryCondition.class);
                if (conditions == null || conditions.size() == 0) {
                    return;
                }
                // update-begin-author:sunjianlei date:20220119 for: 【JTC-573】 过滤空条件查询,防止 sql 拼接多余的 and
                List<QueryCondition> filterConditions = conditions.stream().filter(
                        rule -> oConvertUtils.isNotEmpty(rule.getField())
                                && oConvertUtils.isNotEmpty(rule.getRule())
                                && oConvertUtils.isNotEmpty(rule.getVal())
                ).collect(Collectors.toList());
                if (filterConditions.size() == 0) {
                    return;
                }
                // update-end-author:sunjianlei date:20220119 for: 【JTC-573】 过滤空条件查询,防止 sql 拼接多余的 and
                log.info("---高级查询参数-->" + filterConditions);

                queryWrapper.and(andWrapper -> {
                    for (int i = 0; i < filterConditions.size(); i++) {
                        QueryCondition rule = filterConditions.get(i);
                        if (oConvertUtils.isNotEmpty(rule.getField())
                                && oConvertUtils.isNotEmpty(rule.getRule())
                                && oConvertUtils.isNotEmpty(rule.getVal())) {

                            log.debug("SuperQuery ==> " + rule.toString());

                            //update-begin-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错
                            Object queryValue = rule.getVal();
                            if ("date".equals(rule.getType())) {
                                queryValue = str2Date(rule.getVal(), date_sdf.get());
                            } else if ("datetime".equals(rule.getType())) {
                                queryValue = str2Date(rule.getVal(), datetimeFormat.get());
                            }
                            // update-begin--author:sunjianlei date:20210702 for:【/issues/I3VR8E】高级查询没有类型转换,查询参数都是字符串类型 ----
                            String dbType = rule.getDbType();
                            if (oConvertUtils.isNotEmpty(dbType)) {
                                try {
                                    String valueStr = String.valueOf(queryValue);
                                    switch (dbType.toLowerCase().trim()) {
                                        case "int":
                                            queryValue = Integer.parseInt(valueStr);
                                            break;
                                        case "bigdecimal":
                                            queryValue = new BigDecimal(valueStr);
                                            break;
                                        case "short":
                                            queryValue = Short.parseShort(valueStr);
                                            break;
                                        case "long":
                                            queryValue = Long.parseLong(valueStr);
                                            break;
                                        case "float":
                                            queryValue = Float.parseFloat(valueStr);
                                            break;
                                        case "double":
                                            queryValue = Double.parseDouble(valueStr);
                                            break;
                                        case "boolean":
                                            queryValue = Boolean.parseBoolean(valueStr);
                                            break;
                                        default:
                                    }
                                } catch (Exception e) {
                                    log.error("高级查询值转换失败:", e);
                                }
                            }
                            // update-begin--author:sunjianlei date:20210702 for:【/issues/I3VR8E】高级查询没有类型转换,查询参数都是字符串类型 ----
                            addEasyQuery(andWrapper, fieldColumnMap.get(rule.getField()), QueryRuleEnum.getByValue(rule.getRule()), queryValue);
                            //update-end-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错

                            // 如果拼接方式是OR,就拼接OR
                            if (MatchTypeEnum.OR == matchType && i < (filterConditions.size() - 1)) {
                                andWrapper.or();
                            }
                        }
                    }
                    //return andWrapper;
                });
            } catch (UnsupportedEncodingException e) {
                log.error("--高级查询参数转码失败:" + superQueryParams, e);
            } catch (Exception e) {
                log.error("--高级查询拼接失败:" + e.getMessage());
                e.printStackTrace();
            }
            // update-end--Author:sunjianlei  Date:20200325 for:高级查询的条件要用括号括起来,防止和用户的其他条件冲突 -------
        }
        //log.info(" superQuery getCustomSqlSegment: "+ queryWrapper.getCustomSqlSegment());
    }

    /**
     * 根据所传的值 转化成对应的比较方式
     * 支持><= like in !
     *
     * @param value
     * @return
     */
    public static QueryRuleEnum convert2Rule(Object value) {
        // 避免空数据
        // update-begin-author:taoyan date:20210629 for: 查询条件输入空格导致return null后续判断导致抛出null异常
        if (value == null) {
            return QueryRuleEnum.EQ;
        }
        String val = (value + "").toString().trim();
        if (val.length() == 0) {
            return QueryRuleEnum.EQ;
        }
        // update-end-author:taoyan date:20210629 for: 查询条件输入空格导致return null后续判断导致抛出null异常
        QueryRuleEnum rule = null;

        //update-begin--Author:scott  Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284-------------------
        //TODO 此处规则,只适用于 le lt ge gt
        // step 2 .>= =<
        int length2 = 2;
        int length3 = 3;
        if (rule == null && val.length() >= length3) {
            if (QUERY_SEPARATE_KEYWORD.equals(val.substring(length2, length3))) {
                rule = QueryRuleEnum.getByValue(val.substring(0, 2));
            }
        }
        // step 1 .> <
        if (rule == null && val.length() >= length2) {
            if (QUERY_SEPARATE_KEYWORD.equals(val.substring(1, length2))) {
                rule = QueryRuleEnum.getByValue(val.substring(0, 1));
            }
        }
        //update-end--Author:scott  Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284---------------------

        // step 3 like
        //update-begin-author:taoyan for: /issues/3382 默认带*就走模糊,但是如果只有一个*,那么走等于查询
        if (rule == null && val.equals(STAR)) {
            rule = QueryRuleEnum.EQ;
        }
        //update-end-author:taoyan for: /issues/3382  默认带*就走模糊,但是如果只有一个*,那么走等于查询
        if (rule == null && val.contains(STAR)) {
            if (val.startsWith(STAR) && val.endsWith(STAR)) {
                rule = QueryRuleEnum.LIKE;
            } else if (val.startsWith(STAR)) {
                rule = QueryRuleEnum.LEFT_LIKE;
            } else if (val.endsWith(STAR)) {
                rule = QueryRuleEnum.RIGHT_LIKE;
            }
        }

        // step 4 in
        if (rule == null && val.contains(COMMA)) {
            //TODO in 查询这里应该有个bug  如果一字段本身就是多选 此时用in查询 未必能查询出来
            rule = QueryRuleEnum.IN;
        }
        // step 5 !=
        if (rule == null && val.startsWith(NOT_EQUAL)) {
            rule = QueryRuleEnum.NE;
        }
        // step 6 xx+xx+xx 这种情况适用于如果想要用逗号作精确查询 但是系统默认逗号走in 所以可以用++替换【此逻辑作废】
        if (rule == null && val.indexOf(QUERY_COMMA_ESCAPE) > 0) {
            rule = QueryRuleEnum.EQ_WITH_ADD;
        }

        //update-begin--Author:taoyan  Date:20201229 for:initQueryWrapper组装sql查询条件错误 #284---------------------
        //特殊处理:Oracle的表达式to_date('xxx','yyyy-MM-dd')含有逗号,会被识别为in查询,转为等于查询
        if (rule == QueryRuleEnum.IN && val.indexOf(YYYY_MM_DD) >= 0 && val.indexOf(TO_DATE) >= 0) {
            rule = QueryRuleEnum.EQ;
        }
        //update-end--Author:taoyan  Date:20201229 for:initQueryWrapper组装sql查询条件错误 #284---------------------

        return rule != null ? rule : QueryRuleEnum.EQ;
    }

    /**
     * 替换掉关键字字符
     *
     * @param rule
     * @param value
     * @return
     */
    private static Object replaceValue(QueryRuleEnum rule, Object value) {
        if (rule == null) {
            return null;
        }
        if (!(value instanceof String)) {
            return value;
        }
        String val = (value + "").toString().trim();
        //update-begin-author:taoyan date:20220302 for: 查询条件的值为等号(=)bug #3443
        if (QueryRuleEnum.EQ.getValue().equals(val)) {
            return val;
        }
        //update-end-author:taoyan date:20220302 for: 查询条件的值为等号(=)bug #3443
        if (rule == QueryRuleEnum.LIKE) {
            value = val.substring(1, val.length() - 1);
            //mysql 模糊查询之特殊字符下划线 (_、\)
            value = specialStrConvert(value.toString());
        } else if (rule == QueryRuleEnum.LEFT_LIKE || rule == QueryRuleEnum.NE) {
            value = val.substring(1);
            //mysql 模糊查询之特殊字符下划线 (_、\)
            value = specialStrConvert(value.toString());
        } else if (rule == QueryRuleEnum.RIGHT_LIKE) {
            value = val.substring(0, val.length() - 1);
            //mysql 模糊查询之特殊字符下划线 (_、\)
            value = specialStrConvert(value.toString());
        } else if (rule == QueryRuleEnum.IN) {
            value = val.split(",");
        } else if (rule == QueryRuleEnum.EQ_WITH_ADD) {
            value = val.replaceAll("\\+\\+", COMMA);
        } else {
            //update-begin--Author:scott  Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284-------------------
            if (val.startsWith(rule.getValue())) {
                //TODO 此处逻辑应该注释掉-> 如果查询内容中带有查询匹配规则符号,就会被截取的(比如:>=您好)
                value = val.replaceFirst(rule.getValue(), "");
            } else if (val.startsWith(rule.getCondition() + QUERY_SEPARATE_KEYWORD)) {
                value = val.replaceFirst(rule.getCondition() + QUERY_SEPARATE_KEYWORD, "").trim();
            }
            //update-end--Author:scott  Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284-------------------
        }
        return value;
    }

    private static void addQueryByRule(QueryWrapper<?> queryWrapper, String name, String type, String value, QueryRuleEnum rule) throws ParseException {
        if (oConvertUtils.isNotEmpty(value)) {
            //update-begin--Author:sunjianlei  Date:20220104 for:【JTC-409】修复逗号分割情况下没有转换类型,导致类型严格的数据库查询报错 -------------------
            // 针对数字类型字段,多值查询
            if (value.contains(COMMA)) {
                Object[] temp = Arrays.stream(value.split(COMMA)).map(v -> {
                    try {
                        return QueryGenerator.parseByType(v, type, rule);
                    } catch (ParseException e) {
                        e.printStackTrace();
                        return v;
                    }
                }).toArray();
                addEasyQuery(queryWrapper, name, rule, temp);
                return;
            }
            Object temp = QueryGenerator.parseByType(value, type, rule);
            addEasyQuery(queryWrapper, name, rule, temp);
            //update-end--Author:sunjianlei  Date:20220104 for:【JTC-409】修复逗号分割情况下没有转换类型,导致类型严格的数据库查询报错 -------------------
        }
    }

    /**
     * 根据类型转换给定的值
     *
     * @param value
     * @param type
     * @param rule
     * @return
     * @throws ParseException
     */
    private static Object parseByType(String value, String type, QueryRuleEnum rule) throws ParseException {
        Object temp;
        switch (type) {
            case "class java.lang.Integer":
                temp = Integer.parseInt(value);
                break;
            case "class java.math.BigDecimal":
                temp = new BigDecimal(value);
                break;
            case "class java.lang.Short":
                temp = Short.parseShort(value);
                break;
            case "class java.lang.Long":
                temp = Long.parseLong(value);
                break;
            case "class java.lang.Float":
                temp = Float.parseFloat(value);
                break;
            case "class java.lang.Double":
                temp = Double.parseDouble(value);
                break;
            case "class java.util.Date":
                temp = getDateQueryByRule(value, rule);
                break;
            default:
                temp = value;
                break;
        }
        return temp;
    }

    /**
     * 获取日期类型的值
     *
     * @param value
     * @param rule
     * @return
     * @throws ParseException
     */
    private static Date getDateQueryByRule(String value, QueryRuleEnum rule) throws ParseException {
        Date date = null;
        int length = 10;
        if (value.length() == length) {
            if (rule == QueryRuleEnum.GE) {
                //比较大于
                date = getTime().parse(value + " 00:00:00");
            } else if (rule == QueryRuleEnum.LE) {
                //比较小于
                date = getTime().parse(value + " 23:59:59");
            }
            //TODO 日期类型比较特殊 可能oracle下不一定好使
        }
        if (date == null) {
            date = getTime().parse(value);
        }
        return date;
    }

    /**
     * 根据规则走不同的查询
     *
     * @param queryWrapper QueryWrapper
     * @param name         字段名字
     * @param rule         查询规则
     * @param value        查询条件值
     */
    public static void addEasyQuery(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
        if (value == null || rule == null || oConvertUtils.isEmpty(value)) {
            return;
        }
        name = oConvertUtils.camelToUnderline(name);
        log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}", name, rule.getValue(), value);
        switch (rule) {
            case GT:
                queryWrapper.gt(name, value);
                break;
            case GE:
                queryWrapper.ge(name, value);
                break;
            case LT:
                queryWrapper.lt(name, value);
                break;
            case LE:
                queryWrapper.le(name, value);
                break;
            case EQ:
            case EQ_WITH_ADD:
                queryWrapper.eq(name, value);
                break;
            case NE:
                queryWrapper.ne(name, value);
                break;
            case IN:
                if (value instanceof String) {
                    queryWrapper.in(name, (Object[]) value.toString().split(COMMA));
                } else if (value instanceof String[]) {
                    queryWrapper.in(name, (Object[]) value);
                }
                //update-begin-author:taoyan date:20200909 for:【bug】in 类型多值查询 不适配postgresql #1671
                else if (value.getClass().isArray()) {
                    queryWrapper.in(name, (Object[]) value);
                } else {
                    queryWrapper.in(name, value);
                }
                //update-end-author:taoyan date:20200909 for:【bug】in 类型多值查询 不适配postgresql #1671
                break;
            case LIKE:
                queryWrapper.like(name, value);
                break;
            case LEFT_LIKE:
                queryWrapper.likeLeft(name, value);
                break;
            case RIGHT_LIKE:
                queryWrapper.likeRight(name, value);
                break;
            default:
                log.info("--查询规则未匹配到---");
                break;
        }
    }

    /**
     * @param name
     * @return
     */
    private static boolean judgedIsUselessField(String name) {
        return "class".equals(name) || "ids".equals(name)
                || "page".equals(name) || "rows".equals(name)
                || "sort".equals(name) || "order".equals(name);
    }


    /**
     * 获取请求对应的数据权限规则 TODO 相同列权限多个 有问题
     *
     * @return
     */
    public static Map<String, SysPermissionDataRuleModel> getRuleMap() {
        Map<String, SysPermissionDataRuleModel> ruleMap = new HashMap<>(5);
        List<SysPermissionDataRuleModel> list = DataAutorUtils.loadDataSearchConditon();
        if (list != null && list.size() > 0) {
            if (list.get(0) == null) {
                return ruleMap;
            }
            for (SysPermissionDataRuleModel rule : list) {
                String column = rule.getRuleColumn();
                if (QueryRuleEnum.SQL_RULES.getValue().equals(rule.getRuleConditions())) {
                    column = SQL_RULES_COLUMN + rule.getId();
                }
                ruleMap.put(column, rule);
            }
        }
        return ruleMap;
    }

    private static void addRuleToQueryWrapper(SysPermissionDataRuleModel dataRule, String name, Class propertyType, QueryWrapper<?> queryWrapper) {
        QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
        if (rule.equals(QueryRuleEnum.IN) && !propertyType.equals(String.class)) {
            String[] values = dataRule.getRuleValue().split(",");
            Object[] objs = new Object[values.length];
            for (int i = 0; i < values.length; i++) {
                objs[i] = NumberUtils.parseNumber(values[i], propertyType);
            }
            addEasyQuery(queryWrapper, name, rule, objs);
        } else {
            if (propertyType.equals(String.class)) {
                addEasyQuery(queryWrapper, name, rule, converRuleValue(dataRule.getRuleValue()));
            } else if (propertyType.equals(Date.class)) {
                String dateStr = converRuleValue(dataRule.getRuleValue());
                int length = 10;
                if (dateStr.length() == length) {
                    addEasyQuery(queryWrapper, name, rule, str2Date(dateStr, date_sdf.get()));
                } else {
                    addEasyQuery(queryWrapper, name, rule, str2Date(dateStr, datetimeFormat.get()));
                }
            } else {
                addEasyQuery(queryWrapper, name, rule, NumberUtils.parseNumber(dataRule.getRuleValue(), propertyType));
            }
        }
    }


    public static ThreadLocal<SimpleDateFormat> date_sdf = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    public static ThreadLocal<SimpleDateFormat> datetimeFormat = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    /**
     * 字符串转换成日期
     *
     * @param str
     * @param sdf
     * @return
     */
    public static Date str2Date(String str, SimpleDateFormat sdf) {
        if (null == str || "".equals(str)) {
            return null;
        }
        Date date = null;
        try {
            date = sdf.parse(str);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String converRuleValue(String ruleValue) {
        //String value = JwtUtil.getUserSystemData(ruleValue,null);
        String value = datetimeFormat.get().format(Calendar.getInstance().getTime());
        return value != null ? value : ruleValue;
    }

    /**
     * @param ruleValue:
     * @author: scott
     * @Description: 去掉值前后单引号
     * @date: 2020/3/19 21:26
     * @Return: java.lang.String
     */
    public static String trimSingleQuote(String ruleValue) {
        if (oConvertUtils.isEmpty(ruleValue)) {
            return "";
        }
        if (ruleValue.startsWith(QueryGenerator.SQL_SQ)) {
            ruleValue = ruleValue.substring(1);
        }
        if (ruleValue.endsWith(QueryGenerator.SQL_SQ)) {
            ruleValue = ruleValue.substring(0, ruleValue.length() - 1);
        }
        return ruleValue;
    }

    public static String getSqlRuleValue(String sqlRule) {
        try {
            Set<String> varParams = getSqlRuleParams(sqlRule);
            for (String var : varParams) {
                String tempValue = converRuleValue(var);
                sqlRule = sqlRule.replace("#{" + var + "}", tempValue);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return sqlRule;
    }

    /**
     * 获取sql中的#{key} 这个key组成的set
     */
    public static Set<String> getSqlRuleParams(String sql) {
        if (oConvertUtils.isEmpty(sql)) {
            return null;
        }
        Set<String> varParams = new HashSet<String>();
        String regex = "\\#\\{\\w+\\}";

        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(sql);
        while (m.find()) {
            String var = m.group();
            varParams.add(var.substring(var.indexOf("{") + 1, var.indexOf("}")));
        }
        return varParams;
    }

    /**
     * 获取查询条件
     *
     * @param field
     * @param alias
     * @param value
     * @param isString
     * @return
     */
    public static String getSingleQueryConditionSql(String field, String alias, Object value, boolean isString) {
        return getSingleQueryConditionSql(field, alias, value, isString, null);
    }

    /**
     * 报表获取查询条件 支持多数据源
     *
     * @param field
     * @param alias
     * @param value
     * @param isString
     * @param dataBaseType
     * @return
     */
    public static String getSingleQueryConditionSql(String field, String alias, Object value, boolean isString, String dataBaseType) {
        if (value == null) {
            return "";
        }
        field = alias + oConvertUtils.camelToUnderline(field);
        QueryRuleEnum rule = QueryGenerator.convert2Rule(value);
        return getSingleSqlByRule(rule, field, value, isString, dataBaseType);
    }

    /**
     * 获取单个查询条件的值
     *
     * @param rule
     * @param field
     * @param value
     * @param isString
     * @param dataBaseType
     * @return
     */
    private static String getSingleSqlByRule(QueryRuleEnum rule, String field, Object value, boolean isString, String dataBaseType) {
        String res = "";
        switch (rule) {
            case GT:
                res = field + rule.getValue() + getFieldConditionValue(value, isString, dataBaseType);
                break;
            case GE:
                res = field + rule.getValue() + getFieldConditionValue(value, isString, dataBaseType);
                break;
            case LT:
                res = field + rule.getValue() + getFieldConditionValue(value, isString, dataBaseType);
                break;
            case LE:
                res = field + rule.getValue() + getFieldConditionValue(value, isString, dataBaseType);
                break;
            case EQ:
                res = field + rule.getValue() + getFieldConditionValue(value, isString, dataBaseType);
                break;
            case EQ_WITH_ADD:
                res = field + " = " + getFieldConditionValue(value, isString, dataBaseType);
                break;
            case NE:
                res = field + " <> " + getFieldConditionValue(value, isString, dataBaseType);
                break;
            case IN:
                res = field + " in " + getInConditionValue(value, isString);
                break;
            case LIKE:
                res = field + " like " + getLikeConditionValue(value, QueryRuleEnum.LIKE);
                break;
            case LEFT_LIKE:
                res = field + " like " + getLikeConditionValue(value, QueryRuleEnum.LEFT_LIKE);
                break;
            case RIGHT_LIKE:
                res = field + " like " + getLikeConditionValue(value, QueryRuleEnum.RIGHT_LIKE);
                break;
            default:
                res = field + " = " + getFieldConditionValue(value, isString, dataBaseType);
                break;
        }
        return res;
    }


    /**
     * 获取单个查询条件的值
     *
     * @param rule
     * @param field
     * @param value
     * @param isString
     * @return
     */
    private static String getSingleSqlByRule(QueryRuleEnum rule, String field, Object value, boolean isString) {
        return getSingleSqlByRule(rule, field, value, isString, null);
    }

    /**
     * 获取查询条件的值
     *
     * @param value
     * @param isString
     * @param dataBaseType
     * @return
     */
    private static String getFieldConditionValue(Object value, boolean isString, String dataBaseType) {
        String str = value.toString().trim();
        if (str.startsWith(SymbolConstant.EXCLAMATORY_MARK)) {
            str = str.substring(1);
        } else if (str.startsWith(QueryRuleEnum.GE.getValue())) {
            str = str.substring(2);
        } else if (str.startsWith(QueryRuleEnum.LE.getValue())) {
            str = str.substring(2);
        } else if (str.startsWith(QueryRuleEnum.GT.getValue())) {
            str = str.substring(1);
        } else if (str.startsWith(QueryRuleEnum.LT.getValue())) {
            str = str.substring(1);
        } else if (str.indexOf(QUERY_COMMA_ESCAPE) > 0) {
            str = str.replaceAll("\\+\\+", COMMA);
        }
        if (dataBaseType == null) {
            dataBaseType = getDbType();
        }
        if (isString) {
            if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType)) {
                return " N'" + str + "' ";
            } else {
                return " '" + str + "' ";
            }
        } else {
            // 如果不是字符串 有一种特殊情况 popup调用都走这个逻辑 参数传递的可能是"'admin'"这种格式的
            if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK)) {
                return " N" + str;
            }
            return value.toString();
        }
    }

    private static String getInConditionValue(Object value, boolean isString) {
        //update-begin-author:taoyan date:20210628 for: 查询条件如果输入,导致sql报错
        String[] temp = value.toString().split(",");
        if (temp.length == 0) {
            return "('')";
        }
        if (isString) {
            List<String> res = new ArrayList<>();
            for (String string : temp) {
                if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                    res.add("N'" + string + "'");
                } else {
                    res.add("'" + string + "'");
                }
            }
            return "(" + String.join(",", res) + ")";
        } else {
            return "(" + value.toString() + ")";
        }
        //update-end-author:taoyan date:20210628 for: 查询条件如果输入,导致sql报错
    }

    /**
     * 先根据值判断 走左模糊还是右模糊
     * 最后如果值不带任何标识(*或者%),则再根据ruleEnum判断
     *
     * @param value
     * @param ruleEnum
     * @return
     */
    private static String getLikeConditionValue(Object value, QueryRuleEnum ruleEnum) {
        String str = value.toString().trim();
        if (str.startsWith(SymbolConstant.ASTERISK) && str.endsWith(SymbolConstant.ASTERISK)) {
            if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                return "N'%" + str.substring(1, str.length() - 1) + "%'";
            } else {
                return "'%" + str.substring(1, str.length() - 1) + "%'";
            }
        } else if (str.startsWith(SymbolConstant.ASTERISK)) {
            if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                return "N'%" + str.substring(1) + "'";
            } else {
                return "'%" + str.substring(1) + "'";
            }
        } else if (str.endsWith(SymbolConstant.ASTERISK)) {
            if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                return "N'" + str.substring(0, str.length() - 1) + "%'";
            } else {
                return "'" + str.substring(0, str.length() - 1) + "%'";
            }
        } else {
            if (str.indexOf(SymbolConstant.PERCENT_SIGN) >= 0) {
                if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                    if (str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK)) {
                        return "N" + str;
                    } else {
                        return "N" + "'" + str + "'";
                    }
                } else {
                    if (str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK)) {
                        return str;
                    } else {
                        return "'" + str + "'";
                    }
                }
            } else {

                //update-begin-author:taoyan date:2022-6-30 for: issues/3810 数据权限规则问题
                // 走到这里说明 value不带有任何模糊查询的标识(*或者%)
                if (ruleEnum == QueryRuleEnum.LEFT_LIKE) {
                    if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                        return "N'%" + str + "'";
                    } else {
                        return "'%" + str + "'";
                    }
                } else if (ruleEnum == QueryRuleEnum.RIGHT_LIKE) {
                    if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                        return "N'" + str + "%'";
                    } else {
                        return "'" + str + "%'";
                    }
                } else {
                    if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
                        return "N'%" + str + "%'";
                    } else {
                        return "'%" + str + "%'";
                    }
                }
                //update-end-author:taoyan date:2022-6-30 for: issues/3810 数据权限规则问题

            }
        }
    }

    /**
     * 根据权限相关配置生成相关的SQL 语句
     *
     * @param clazz
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static String installAuthJdbc(Class<?> clazz) {
        StringBuffer sb = new StringBuffer();
        //权限查询
        Map<String, SysPermissionDataRuleModel> ruleMap = getRuleMap();
        PropertyDescriptor[] origDescriptors = PropertyUtils.getPropertyDescriptors(clazz);
        String sqlAnd = " and ";
        for (String c : ruleMap.keySet()) {
            if (oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)) {
                sb.append(sqlAnd + getSqlRuleValue(ruleMap.get(c).getRuleValue()));
            }
        }
        String name, column;
        for (int i = 0; i < origDescriptors.length; i++) {
            name = origDescriptors[i].getName();
            if (judgedIsUselessField(name)) {
                continue;
            }
            if (ruleMap.containsKey(name)) {
                column = getTableFieldName(clazz, name);
                if (column == null) {
                    continue;
                }
                SysPermissionDataRuleModel dataRule = ruleMap.get(name);
                QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
                Class propType = origDescriptors[i].getPropertyType();
                boolean isString = propType.equals(String.class);
                Object value;
                if (isString) {
                    value = converRuleValue(dataRule.getRuleValue());
                } else {
                    value = NumberUtils.parseNumber(dataRule.getRuleValue(), propType);
                }
                String filedSql = getSingleSqlByRule(rule, oConvertUtils.camelToUnderline(column), value, isString);
                sb.append(sqlAnd + filedSql);
            }
        }
        log.info("query auth sql is:" + sb.toString());
        return sb.toString();
    }

    /**
     * 根据权限相关配置 组装mp需要的权限
     *
     * @param queryWrapper
     * @param clazz
     * @return
     */
    public static void installAuthMplus(QueryWrapper<?> queryWrapper, Class<?> clazz) {
        //权限查询
        Map<String, SysPermissionDataRuleModel> ruleMap = getRuleMap();
        PropertyDescriptor[] origDescriptors = PropertyUtils.getPropertyDescriptors(clazz);
        for (String c : ruleMap.keySet()) {
            if (oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)) {
                queryWrapper.and(i -> i.apply(getSqlRuleValue(ruleMap.get(c).getRuleValue())));
            }
        }
        String name, column;
        for (int i = 0; i < origDescriptors.length; i++) {
            name = origDescriptors[i].getName();
            if (judgedIsUselessField(name)) {
                continue;
            }
            column = getTableFieldName(clazz, name);
            if (column == null) {
                continue;
            }
            if (ruleMap.containsKey(name)) {
                addRuleToQueryWrapper(ruleMap.get(name), column, origDescriptors[i].getPropertyType(), queryWrapper);
            }
        }
    }

    /**
     * 转换sql中的系统变量
     *
     * @param sql
     * @return
     */
    public static String convertSystemVariables(String sql) {
        return getSqlRuleValue(sql);
    }

    /**
     * 获取所有配置的权限 返回sql字符串 不受字段限制 配置什么就拿到什么
     *
     * @return
     */
    public static String getAllConfigAuth() {
        StringBuffer sb = new StringBuffer();
        //权限查询
        Map<String, SysPermissionDataRuleModel> ruleMap = getRuleMap();
        String sqlAnd = " and ";
        for (String c : ruleMap.keySet()) {
            SysPermissionDataRuleModel dataRule = ruleMap.get(c);
            String ruleValue = dataRule.getRuleValue();
            if (oConvertUtils.isEmpty(ruleValue)) {
                continue;
            }
            if (oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)) {
                sb.append(sqlAnd + getSqlRuleValue(ruleValue));
            } else {
                boolean isString = false;
                ruleValue = ruleValue.trim();
                if (ruleValue.startsWith("'") && ruleValue.endsWith("'")) {
                    isString = true;
                    ruleValue = ruleValue.substring(1, ruleValue.length() - 1);
                }
                QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
                String value = converRuleValue(ruleValue);
                String filedSql = getSingleSqlByRule(rule, c, value, isString);
                sb.append(sqlAnd + filedSql);
            }
        }
        log.info("query auth sql is = " + sb.toString());
        return sb.toString();
    }


    /**
     * 获取系统数据库类型
     */
    private static String getDbType() {
        return CommonUtils.getDatabaseType();
    }


    /**
     * 获取class的 包括父类的
     *
     * @param clazz
     * @return
     */
    private static List<Field> getClassFields(Class<?> clazz) {
        List<Field> list = new ArrayList<Field>();
        Field[] fields;
        do {
            fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                list.add(fields[i]);
            }
            clazz = clazz.getSuperclass();
        } while (clazz != Object.class && clazz != null);
        return list;
    }

    /**
     * 获取表字段名
     *
     * @param clazz
     * @param name
     * @return
     */
    private static String getTableFieldName(Class<?> clazz, String name) {
        try {
            //如果字段加注解了@TableField(exist = false),不走DB查询
            Field field = null;
            try {
                field = clazz.getDeclaredField(name);
            } catch (NoSuchFieldException e) {
                //e.printStackTrace();
            }

            //如果为空,则去父类查找字段
            if (field == null) {
                List<Field> allFields = getClassFields(clazz);
                List<Field> searchFields = allFields.stream().filter(a -> a.getName().equals(name)).collect(Collectors.toList());
                if (searchFields != null && searchFields.size() > 0) {
                    field = searchFields.get(0);
                }
            }

            if (field != null) {
                TableField tableField = field.getAnnotation(TableField.class);
                if (tableField != null) {
                    if (tableField.exist() == false) {
                        //如果设置了TableField false 这个字段不需要处理
                        return null;
                    } else {
                        String column = tableField.value();
                        //如果设置了TableField value 这个字段是实体字段
                        if (!"".equals(column)) {
                            return column;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return name;
    }

    /**
     * mysql 模糊查询之特殊字符下划线 (_、\)
     *
     * @param value:
     * @Return: java.lang.String
     */
    private static String specialStrConvert(String value) {
        if (DataBaseConstant.DB_TYPE_MYSQL.equals(getDbType()) || DataBaseConstant.DB_TYPE_MARIADB.equals(getDbType())) {
            String[] specialStr = QueryGenerator.LIKE_MYSQL_SPECIAL_STRS.split(",");
            for (String str : specialStr) {
                if (value.indexOf(str) != -1) {
                    value = value.replace(str, "\\" + str);
                }
            }
        }
        return value;
    }
}

10

java 复制代码
package com.hdx.contractor.util.query;

/**
 * Query 规则 常量
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
public enum QueryRuleEnum {

    /**查询规则 大于*/
    GT(">","gt","大于"),
    /**查询规则 大于等于*/
    GE(">=","ge","大于等于"),
    /**查询规则 小于*/
    LT("<","lt","小于"),
    /**查询规则 小于等于*/
    LE("<=","le","小于等于"),
    /**查询规则 等于*/
    EQ("=","eq","等于"),
    /**查询规则 不等于*/
    NE("!=","ne","不等于"),
    /**查询规则 包含*/
    IN("IN","in","包含"),
    /**查询规则 全模糊*/
    LIKE("LIKE","like","全模糊"),
    /**查询规则 左模糊*/
    LEFT_LIKE("LEFT_LIKE","left_like","左模糊"),
    /**查询规则 右模糊*/
    RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"),
    /**查询规则 带加号等于*/
    EQ_WITH_ADD("EQWITHADD","eq_with_add","带加号等于"),
    /**查询规则 多词模糊匹配*/
    LIKE_WITH_AND("LIKEWITHAND","like_with_and","多词模糊匹配------------暂时未用上"),
    /**查询规则 自定义SQL片段*/
    SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段");

    private String value;
    
    private String condition; 

    private String msg;

    QueryRuleEnum(String value, String condition, String msg){
        this.value = value;
        this.condition = condition;
        this.msg = msg;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCondition() {
		return condition;
	}

	public void setCondition(String condition) {
		this.condition = condition;
	}

	public static QueryRuleEnum getByValue(String value){
    	if(oConvertUtils.isEmpty(value)) {
    		return null;
    	}
        for(QueryRuleEnum val :values()){
            if (val.getValue().equals(value) || val.getCondition().equals(value)){
                return val;
            }
        }
        return  null;
    }
}

11

java 复制代码
package com.hdx.contractor.util.query;

import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * sql注入处理工具类
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
@Slf4j
public class SqlInjectionUtil {
	/**
	 * sign 用于表字典加签的盐值【SQL漏洞】
	 * (上线修改值 20200501,同步修改前端的盐值)
	 */
	private final static String TABLE_DICT_SIGN_SALT = "20200501";
	private final static String XSS_STR = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|user()";

	/**
	 * 正则 user() 匹配更严谨
	 */
	private final static String REGULAR_EXPRE_USER = "user[\\s]*\\([\\s]*\\)";
    /**正则 show tables*/
	private final static String SHOW_TABLES = "show\\s+tables";

	/**
	 * sql注释的正则
	 */
	private final static Pattern SQL_ANNOTATION = Pattern.compile("/\\*.*\\*/");

	/**
	 * 针对表字典进行额外的sign签名校验(增加安全机制)
	 * @param dictCode:
	 * @param sign:
	 * @param request:
	 * @Return: void
	 */
	public static void checkDictTableSign(String dictCode, String sign, HttpServletRequest request) {
		//表字典SQL注入漏洞,签名校验
		String accessToken = request.getHeader("X-Access-Token");
		String signStr = dictCode + SqlInjectionUtil.TABLE_DICT_SIGN_SALT + accessToken;
		String javaSign = SecureUtil.md5(signStr);
		if (!javaSign.equals(sign)) {
			log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);
			throw new RuntimeException("无权限访问!");
		}
		log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode);
	}

	/**
	 * sql注入过滤处理,遇到注入关键字抛异常
	 * @param value
	 */
	public static void filterContent(String value) {
		filterContent(value, null);
	}

	/**
	 * sql注入过滤处理,遇到注入关键字抛异常
	 * 
	 * @param value
	 * @return
	 */
	public static void filterContent(String value, String customXssString) {
		if (value == null || "".equals(value)) {
			return;
		}
		// 校验sql注释 不允许有sql注释
		checkSqlAnnotation(value);
		// 统一转为小写
		value = value.toLowerCase();
		//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
		//value = value.replaceAll("/\\*.*\\*/","");

		String[] xssArr = XSS_STR.split("\\|");
		for (int i = 0; i < xssArr.length; i++) {
			if (value.indexOf(xssArr[i]) > -1) {
				log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
			}
		}
		//update-begin-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
		if (customXssString != null) {
			String[] xssArr2 = customXssString.split("\\|");
			for (int i = 0; i < xssArr2.length; i++) {
				if (value.indexOf(xssArr2[i]) > -1) {
					log.error("请注意,存在SQL注入关键词---> {}", xssArr2[i]);
					log.error("请注意,值可能存在SQL注入风险!---> {}", value);
					throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
				}
			}
		}
		//update-end-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
		if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
			throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
		}
		return;
	}

	/**
	 * sql注入过滤处理,遇到注入关键字抛异常
	 * @param values
	 */
	public static void filterContent(String[] values) {
		filterContent(values, null);
	}

	/**
	 * sql注入过滤处理,遇到注入关键字抛异常
	 * 
	 * @param values
	 * @return
	 */
	public static void filterContent(String[] values, String customXssString) {
		String[] xssArr = XSS_STR.split("\\|");
		for (String value : values) {
			if (value == null || "".equals(value)) {
				return;
			}
			// 校验sql注释 不允许有sql注释
			checkSqlAnnotation(value);
			// 统一转为小写
			value = value.toLowerCase();
			//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
			//value = value.replaceAll("/\\*.*\\*/","");

			for (int i = 0; i < xssArr.length; i++) {
				if (value.indexOf(xssArr[i]) > -1) {
					log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
					log.error("请注意,值可能存在SQL注入风险!---> {}", value);
					throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
				}
			}
			//update-begin-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
			if (customXssString != null) {
				String[] xssArr2 = customXssString.split("\\|");
				for (int i = 0; i < xssArr2.length; i++) {
					if (value.indexOf(xssArr2[i]) > -1) {
						log.error("请注意,存在SQL注入关键词---> {}", xssArr2[i]);
						log.error("请注意,值可能存在SQL注入风险!---> {}", value);
						throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
					}
				}
			}
			//update-end-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
			if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
			}
		}
		return;
	}

	/**
	 * 【提醒:不通用】
	 * 仅用于字典条件SQL参数,注入过滤
	 *
	 * @param value
	 * @return
	 */
	//@Deprecated
	public static void specialFilterContentForDictSql(String value) {
		String specialXssStr = " exec |extractvalue|updatexml| insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|user()";
		String[] xssArr = specialXssStr.split("\\|");
		if (value == null || "".equals(value)) {
			return;
		}
		// 校验sql注释 不允许有sql注释
		checkSqlAnnotation(value);
		// 统一转为小写
		value = value.toLowerCase();
		//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
		//value = value.replaceAll("/\\*.*\\*/","");

		for (int i = 0; i < xssArr.length; i++) {
			if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
				log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
			}
		}
		if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
			throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
		}
		return;
	}


    /**
	 * 【提醒:不通用】
     *  仅用于Online报表SQL解析,注入过滤
     * @param value
     * @return
     */
	//@Deprecated
	public static void specialFilterContentForOnlineReport(String value) {
		String specialXssStr = " exec |extractvalue|updatexml| insert | delete | update | drop | chr | mid | master | truncate | char | declare |user()";
		String[] xssArr = specialXssStr.split("\\|");
		if (value == null || "".equals(value)) {
			return;
		}
		// 校验sql注释 不允许有sql注释
		checkSqlAnnotation(value);
		// 统一转为小写
		value = value.toLowerCase();
		//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
		//value = value.replaceAll("/\\*.*\\*/"," ");

		for (int i = 0; i < xssArr.length; i++) {
			if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
				log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
			}
		}

		if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
			throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
		}
		return;
	}


	/**
	 * 判断给定的字段是不是类中的属性
	 * @param field 字段名
	 * @param clazz 类对象
	 * @return
	 */
	public static boolean isClassField(String field, Class clazz){
		Field[] fields = clazz.getDeclaredFields();
		for(int i=0;i<fields.length;i++){
			String fieldName = fields[i].getName();
			String tableColumnName = oConvertUtils.camelToUnderline(fieldName);
			if(fieldName.equalsIgnoreCase(field) || tableColumnName.equalsIgnoreCase(field)){
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断给定的多个字段是不是类中的属性
	 * @param fieldSet 字段名set
	 * @param clazz 类对象
	 * @return
	 */
	public static boolean isClassField(Set<String> fieldSet, Class clazz){
		Field[] fields = clazz.getDeclaredFields();
		for(String field: fieldSet){
			boolean exist = false;
			for(int i=0;i<fields.length;i++){
				String fieldName = fields[i].getName();
				String tableColumnName = oConvertUtils.camelToUnderline(fieldName);
				if(fieldName.equalsIgnoreCase(field) || tableColumnName.equalsIgnoreCase(field)){
					exist = true;
					break;
				}
			}
			if(!exist){
				return false;
			}
		}
		return true;
	}

	/**
	 * 校验是否有sql注释 
	 * @return
	 */
	public static void checkSqlAnnotation(String str){
		Matcher matcher = SQL_ANNOTATION.matcher(str);
		if(matcher.find()){
			String error = "请注意,值可能存在SQL注入风险---> \\*.*\\";
			log.error(error);
			throw new RuntimeException(error);
		}
	}
}

12

java 复制代码
package com.hdx.contractor.util.query;

/**
 * @Description: 符号和特殊符号常用类
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
public class SymbolConstant {

    /**
     * 符号:点
     */
    public static final String SPOT = ".";

    /**
     * 符号:双斜杠
     */
    public static final String DOUBLE_BACKSLASH = "\\";

    /**
     * 符号:冒号
     */
    public static final String COLON = ":";

    /**
     * 符号:逗号
     */
    public static final String COMMA = ",";

    /**
     * 符号:左花括号 }
     */
    public static final String LEFT_CURLY_BRACKET = "{";

    /**
     * 符号:右花括号 }
     */
    public static final String RIGHT_CURLY_BRACKET = "}";

    /**
     * 符号:井号 #
     */
    public static final String WELL_NUMBER = "#";

    /**
     * 符号:单斜杠
     */
    public static final String SINGLE_SLASH = "/";

    /**
     * 符号:双斜杠
     */
    public static final String DOUBLE_SLASH = "//";

    /**
     * 符号:感叹号
     */
    public static final String EXCLAMATORY_MARK = "!";

    /**
     * 符号:下划线
     */
    public static final String UNDERLINE = "_";

    /**
     * 符号:单引号
     */
    public static final String SINGLE_QUOTATION_MARK = "'";

    /**
     * 符号:星号
     */
    public static final String ASTERISK = "*";

    /**
     * 符号:百分号
     */
    public static final String PERCENT_SIGN = "%";

    /**
     * 符号:美元 $
     */
    public static final String DOLLAR = "$";

    /**
     * 符号:和 &
     */
    public static final String AND = "&";

    /**
     * 符号:和 =
     */
    public static final String equals = "=";

    /**
     * 符号:../
     */
    public static final String SPOT_SINGLE_SLASH = "../";

    /**
     * 符号:..\\
     */
    public static final String SPOT_DOUBLE_BACKSLASH = "..\\";

    /**
     * 系统变量前缀 #{
     */
    public static final String SYS_VAR_PREFIX = "#{";

    /**
     * 符号 {{
     */
    public static final String DOUBLE_LEFT_CURLY_BRACKET = "{{";

    /**
     * 符号:[
     */
    public static final String SQUARE_BRACKETS_LEFT = "[";
    /**
     * 符号:]
     */
    public static final String SQUARE_BRACKETS_RIGHT = "]";

}

13

java 复制代码
package com.hdx.contractor.util.query;

import java.util.Date;

/**
 * <p>
 * 菜单权限规则表
 * </p>
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
public class SysPermissionDataRuleModel {

    /**
     * id
     */
    private String id;

    /**
     * 对应的菜单id
     */
    private String permissionId;

    /**
     * 规则名称
     */
    private String ruleName;

    /**
     * 字段
     */
    private String ruleColumn;

    /**
     * 条件
     */
    private String ruleConditions;

    /**
     * 规则值
     */
    private String ruleValue;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 创建人
     */
    private String createBy;

    /**
     * 修改时间
     */
    private Date updateTime;

    /**
     * 修改人
     */
    private String updateBy;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPermissionId() {
        return permissionId;
    }

    public void setPermissionId(String permissionId) {
        this.permissionId = permissionId;
    }

    public String getRuleName() {
        return ruleName;
    }

    public void setRuleName(String ruleName) {
        this.ruleName = ruleName;
    }

    public String getRuleColumn() {
        return ruleColumn;
    }

    public void setRuleColumn(String ruleColumn) {
        this.ruleColumn = ruleColumn;
    }

    public String getRuleConditions() {
        return ruleConditions;
    }

    public void setRuleConditions(String ruleConditions) {
        this.ruleConditions = ruleConditions;
    }

    public String getRuleValue() {
        return ruleValue;
    }

    public void setRuleValue(String ruleValue) {
        this.ruleValue = ruleValue;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getCreateBy() {
        return createBy;
    }

    public void setCreateBy(String createBy) {
        this.createBy = createBy;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getUpdateBy() {
        return updateBy;
    }

    public void setUpdateBy(String updateBy) {
        this.updateBy = updateBy;
    }
}

14

java 复制代码
package com.hdx.contractor.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * Spring Context 工具类
 * @Author: xu
 * @Date: 2024-10-06
 * @Version: V1.0
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {
	public static ApplicationContext applicationContext; 

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		SpringContextUtils.applicationContext = applicationContext;
	}

	public static Object getBean(String name) {
		return applicationContext.getBean(name);
	}

	public static <T> T getBean(Class<T> requiredType) {
		return applicationContext.getBean(requiredType);
	}

	public static <T> T getBean(String name, Class<T> requiredType) {
		return applicationContext.getBean(name, requiredType);
	}

	public static boolean containsBean(String name) {
		return applicationContext.containsBean(name);
	}

	public static boolean isSingleton(String name) {
		return applicationContext.isSingleton(name);
	}

	public static Class<? extends Object> getType(String name) {
		return applicationContext.getType(name);
	}

	/**
	 * 获取HttpServletRequest
	 */
	public static HttpServletRequest getHttpServletRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}

	/**
	 * 获取applicationContext
	 *
	 * @return
	 */
	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}


}
相关推荐
ZWZhangYu12 小时前
【MyBatis源码分析】使用 Java 动态代理,实现一个简单的插件机制
java·python·mybatis
程序员大金14 小时前
基于SSM+Vue的个性化旅游推荐系统
前端·vue.js·mysql·java-ee·tomcat·mybatis·旅游
奔跑草-18 小时前
【服务器】MyBatis是如何在java中使用并进行分页的?
java·服务器·mybatis
秋恬意1 天前
接口绑定有几种实现方式
mybatis
谢家小布柔1 天前
MyBatis入门的详细应用实例
mybatis
雅俗共赏zyyyyyy1 天前
Mybatis分页插件的使用问题记录
mybatis
陈大爷(有低保)1 天前
mybatisPlus使用步骤详解
java·后端·mybatis
武子康2 天前
Java-31 深入浅出 Spring - IoC 基础 启动IoC XML与注解结合的方式 配置改造 applicationContext.xml
java·大数据·spring·mybatis·springboot
猿java2 天前
这样理解 MyBatis缓存机制,真香!
java·后端·mybatis
豪宇刘2 天前
深入了解 MyBatis:简化 Java 数据库交互
java·数据库·mybatis