|
|
package com.utils;
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Iterator;
|
|
|
import java.util.Map;
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
|
|
|
import com.baomidou.mybatisplus.mapper.Wrapper;
|
|
|
|
|
|
/**
|
|
|
* Mybatis-Plus工具类
|
|
|
*
|
|
|
* 核心职责:提供MyBatis-Plus查询条件的便捷构建方法
|
|
|
*
|
|
|
* 功能特性:
|
|
|
* 1. 驼峰转下划线字段名转换
|
|
|
* 2. 对象属性到查询条件的自动转换
|
|
|
* 3. 多种查询条件构建(等值查询、模糊查询、范围查询、排序)
|
|
|
* 4. 支持前缀的字段名处理
|
|
|
*
|
|
|
* 技术依赖:
|
|
|
* - MyBatis-Plus: 查询条件构建
|
|
|
* - Hutool: Bean到Map的转换
|
|
|
* - Apache Commons Lang3: 字符串工具
|
|
|
*/
|
|
|
public class MPUtil {
|
|
|
|
|
|
// 下划线字符常量
|
|
|
public static final char UNDERLINE = '_';
|
|
|
|
|
|
/**
|
|
|
* MyBatis Plus allEQ 表达式转换(带前缀)
|
|
|
* 将Java Bean转换为数据库字段名的等值查询条件Map
|
|
|
*
|
|
|
* @param bean 实体对象
|
|
|
* @param pre 字段前缀(如表别名)
|
|
|
* @return 转换后的查询条件Map
|
|
|
*/
|
|
|
public static Map allEQMapPre(Object bean, String pre) {
|
|
|
Map<String, Object> map = BeanUtil.beanToMap(bean);
|
|
|
return camelToUnderlineMap(map, pre);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* MyBatis Plus allEQ 表达式转换(无前缀)
|
|
|
* 将Java Bean转换为数据库字段名的等值查询条件Map
|
|
|
*
|
|
|
* @param bean 实体对象
|
|
|
* @return 转换后的查询条件Map
|
|
|
*/
|
|
|
public static Map allEQMap(Object bean) {
|
|
|
Map<String, Object> map = BeanUtil.beanToMap(bean);
|
|
|
return camelToUnderlineMap(map, "");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 构建带前缀的模糊查询条件
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param bean 实体对象
|
|
|
* @param pre 字段前缀
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper allLikePre(Wrapper wrapper, Object bean, String pre) {
|
|
|
Map<String, Object> map = BeanUtil.beanToMap(bean);
|
|
|
Map result = camelToUnderlineMap(map, pre);
|
|
|
return genLike(wrapper, result);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 构建模糊查询条件
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param bean 实体对象
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper allLike(Wrapper wrapper, Object bean) {
|
|
|
Map result = BeanUtil.beanToMap(bean, true, true);
|
|
|
return genLike(wrapper, result);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 生成模糊查询条件
|
|
|
* 为Map中的每个字段添加LIKE查询条件
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param param 查询参数Map
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper genLike(Wrapper wrapper, Map param) {
|
|
|
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
|
|
|
int i = 0;
|
|
|
while (it.hasNext()) {
|
|
|
if (i > 0) wrapper.and(); // 从第二个条件开始添加AND连接
|
|
|
Map.Entry<String, Object> entry = it.next();
|
|
|
String key = entry.getKey();
|
|
|
String value = (String) entry.getValue();
|
|
|
wrapper.like(key, value); // 添加LIKE条件
|
|
|
i++;
|
|
|
}
|
|
|
return wrapper;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 构建模糊查询或等值查询条件
|
|
|
* 根据值是否包含%决定使用LIKE还是EQ
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param bean 实体对象
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper likeOrEq(Wrapper wrapper, Object bean) {
|
|
|
Map result = BeanUtil.beanToMap(bean, true, true);
|
|
|
return genLikeOrEq(wrapper, result);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 生成模糊查询或等值查询条件
|
|
|
* 值包含%使用LIKE,否则使用EQ
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param param 查询参数Map
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper genLikeOrEq(Wrapper wrapper, Map param) {
|
|
|
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
|
|
|
int i = 0;
|
|
|
while (it.hasNext()) {
|
|
|
if (i > 0) wrapper.and();
|
|
|
Map.Entry<String, Object> entry = it.next();
|
|
|
String key = entry.getKey();
|
|
|
if (entry.getValue().toString().contains("%")) {
|
|
|
// 值包含%,使用LIKE查询(移除%符号)
|
|
|
wrapper.like(key, entry.getValue().toString().replace("%", ""));
|
|
|
} else {
|
|
|
// 值不包含%,使用等值查询
|
|
|
wrapper.eq(key, entry.getValue());
|
|
|
}
|
|
|
i++;
|
|
|
}
|
|
|
return wrapper;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 构建等值查询条件
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param bean 实体对象
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper allEq(Wrapper wrapper, Object bean) {
|
|
|
Map result = BeanUtil.beanToMap(bean, true, true);
|
|
|
return genEq(wrapper, result);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 生成等值查询条件
|
|
|
* 为Map中的每个字段添加EQ查询条件
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param param 查询参数Map
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper genEq(Wrapper wrapper, Map param) {
|
|
|
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
|
|
|
int i = 0;
|
|
|
while (it.hasNext()) {
|
|
|
if (i > 0) wrapper.and();
|
|
|
Map.Entry<String, Object> entry = it.next();
|
|
|
String key = entry.getKey();
|
|
|
wrapper.eq(key, entry.getValue()); // 添加等值条件
|
|
|
i++;
|
|
|
}
|
|
|
return wrapper;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 构建范围查询条件
|
|
|
* 处理以_start和_end结尾的字段,生成BETWEEN条件
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param params 查询参数Map
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper between(Wrapper wrapper, Map<String, Object> params) {
|
|
|
for (String key : params.keySet()) {
|
|
|
String columnName = "";
|
|
|
if (key.endsWith("_start")) {
|
|
|
// 处理开始范围条件
|
|
|
columnName = key.substring(0, key.indexOf("_start"));
|
|
|
if (StringUtils.isNotBlank(params.get(key).toString())) {
|
|
|
wrapper.ge(columnName, params.get(key)); // 大于等于
|
|
|
}
|
|
|
}
|
|
|
if (key.endsWith("_end")) {
|
|
|
// 处理结束范围条件
|
|
|
columnName = key.substring(0, key.indexOf("_end"));
|
|
|
if (StringUtils.isNotBlank(params.get(key).toString())) {
|
|
|
wrapper.le(columnName, params.get(key)); // 小于等于
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return wrapper;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 构建排序条件
|
|
|
* 根据sort和order参数生成排序条件
|
|
|
*
|
|
|
* @param wrapper MyBatis-Plus查询包装器
|
|
|
* @param params 查询参数Map
|
|
|
* @return 构建后的查询包装器
|
|
|
*/
|
|
|
public static Wrapper sort(Wrapper wrapper, Map<String, Object> params) {
|
|
|
String order = "";
|
|
|
if (params.get("order") != null && StringUtils.isNotBlank(params.get("order").toString())) {
|
|
|
order = params.get("order").toString();
|
|
|
}
|
|
|
if (params.get("sort") != null && StringUtils.isNotBlank(params.get("sort").toString())) {
|
|
|
if (order.equalsIgnoreCase("desc")) {
|
|
|
wrapper.orderDesc(Arrays.asList(params.get("sort"))); // 降序
|
|
|
} else {
|
|
|
wrapper.orderAsc(Arrays.asList(params.get("sort"))); // 升序
|
|
|
}
|
|
|
}
|
|
|
return wrapper;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 驼峰格式字符串转换为下划线格式字符串
|
|
|
* 将Java字段名转换为数据库字段名
|
|
|
*
|
|
|
* @param param 驼峰格式字符串
|
|
|
* @return 下划线格式字符串
|
|
|
*/
|
|
|
public static String camelToUnderline(String param) {
|
|
|
if (param == null || "".equals(param.trim())) {
|
|
|
return "";
|
|
|
}
|
|
|
int len = param.length();
|
|
|
StringBuilder sb = new StringBuilder(len);
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
char c = param.charAt(i);
|
|
|
if (Character.isUpperCase(c)) {
|
|
|
// 遇到大写字母,在前面添加下划线并转为小写
|
|
|
sb.append(UNDERLINE);
|
|
|
sb.append(Character.toLowerCase(c));
|
|
|
} else {
|
|
|
sb.append(c);
|
|
|
}
|
|
|
}
|
|
|
return sb.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 测试方法
|
|
|
*/
|
|
|
public static void main(String[] ages) {
|
|
|
System.out.println(camelToUnderline("ABCddfANM")); // 输出: a_b_cddf_a_n_m
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 将Map中的键从驼峰命名转换为下划线命名
|
|
|
*
|
|
|
* @param param 原始Map
|
|
|
* @param pre 字段前缀
|
|
|
* @return 转换后的Map
|
|
|
*/
|
|
|
public static Map camelToUnderlineMap(Map param, String pre) {
|
|
|
Map<String, Object> newMap = new HashMap<String, Object>();
|
|
|
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
|
|
|
while (it.hasNext()) {
|
|
|
Map.Entry<String, Object> entry = it.next();
|
|
|
String key = entry.getKey();
|
|
|
String newKey = camelToUnderline(key); // 转换字段名
|
|
|
|
|
|
// 处理前缀
|
|
|
if (pre.endsWith(".")) {
|
|
|
newMap.put(pre + newKey, entry.getValue());
|
|
|
} else if (StringUtils.isEmpty(pre)) {
|
|
|
newMap.put(newKey, entry.getValue());
|
|
|
} else {
|
|
|
newMap.put(pre + "." + newKey, entry.getValue());
|
|
|
}
|
|
|
}
|
|
|
return newMap;
|
|
|
}
|
|
|
} |