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 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 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 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> it = param.entrySet().iterator(); int i = 0; while (it.hasNext()) { if (i > 0) wrapper.and(); // 从第二个条件开始添加AND连接 Map.Entry 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> it = param.entrySet().iterator(); int i = 0; while (it.hasNext()) { if (i > 0) wrapper.and(); Map.Entry 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> it = param.entrySet().iterator(); int i = 0; while (it.hasNext()) { if (i > 0) wrapper.and(); Map.Entry 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 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 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 newMap = new HashMap(); Iterator> it = param.entrySet().iterator(); while (it.hasNext()) { Map.Entry 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; } }