mybatis like % _ 字符转义 (对象直接转,无需一个一个转)

因为SQL中 LIKE 对于 %  \这些符号是通配符,若要作为正常参数查询需要转译。

字符串模糊匹配:使用 like 关键字

%:表示一个或者是多个字符

_:表示一个字符

如果涉及一个对象多个模糊查询字段,如果一个一个进行转义太过麻烦,因此写了一个通过对象直接对对象内所有String字段进行转义的工具类,mybatis-plus同样适用

代码如下:

package com.cmict.smartsupervision.supdomain.core.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;


/**
 * @Author: Mr.Z
 * @Date: 2024年02月02日 9:09
 **/
@Slf4j
public class QueryParameterUtils {
    /**
     * 对Bean对象内String参数的 % _ 空格 进行转换
     * 注意:bean对象要具有无参构造
     * @param instance
     * @return
     * @param <T>
     */
    public static <T> T convertStringData(T instance){
        T newInstance = null;
        try {
            Class<?> clazz = instance.getClass();
            newInstance = (T) clazz.newInstance();

            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                //确保私有变量可以访问
                field.setAccessible(true);
                if (field.getType() == String.class) {
                    String originalValue = (String) field.get(instance);
                    if (originalValue != null) {
                        // 对字符串进行转换
                        String escapedValue = convertString(originalValue);
                        field.set(newInstance, escapedValue);
                    } else {
                        // 保持null值不变
                        field.set(newInstance, originalValue);
                    }
                } else {
                    // 保持非String类型的字段原值
                    field.set(newInstance, field.get(instance));
                }
            }
        }catch (Exception e){
            log.error(e.getMessage());
        }finally {
            return newInstance;
        }
    }

    /**
     * 对Bean对象内String参数的 % _ 空格 进行转换 (针对实现了序列化的类)
     * 注意:bean对象要具有无参构造
     * 注意,这种方式实际上是创建了一个原始对象的深拷贝,对于大型或复杂的对象可能会有一定的性能开销。
     * 另外,如果类中有自定义的序列化逻辑,则需要确保它不会影响到此方法的正确性。
     * @param instance
     * @return
     * @param <T>
     */
    public static <T extends Serializable> T convertStringDataBySerializable(T instance){
        T newInstance = null;
        try {
            // 序列化并反序列化实例以复制其所有字段(包括私有字段)
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(instance);
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
            newInstance = (T) ois.readObject();

            Class<?> clazz = instance.getClass();
            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                field.setAccessible(true);
                if (field.getType() == String.class) {
                    String originalValue = (String) field.get(instance);
                    if (originalValue != null) {
                        //对字符串进行转换
                        String escapedValue = convertString(originalValue); 
                        field.set(newInstance, escapedValue);
                    } else {
                        // 保持null值不变
                        field.set(newInstance, originalValue);
                    }
                }
            }
        }catch (Exception e){
            log.error(e.getMessage());
        }finally {
            return newInstance;
        }
    }



    /**
     * 对模糊查询的 空格  % 和 _ 进行转义  转换
     * @param str
     * @return
     */
    public static String convertString(String str){
        if (ObjectUtils.isEmpty(str)){
            return str;
        }
        //只对查询条件为特殊符号的时候起作用  如果同时输入多个特殊字符,需将此判断条件去除,但是这样如果查询条件中有特殊字符也会对其进行转义
        if ("%".equals(str) || "_".equals(str) || "'".equals(str) || "\"".equals(str) || "\\".equals(str)){
            return str.replace("\\", "\\\\")
                    .replace("\"", "\\"+"\"")
                    .replace("%", "\\%")
                    .replace("'", "\\'")
                    .replace("_", "\\_");
        }
        return str;
    }


    /**
     * 对URL进行转换
     * @param value
     * @return
     */
    private static String escapeForUrl(String value) {
        try {
            if (ObjectUtils.isNotEmpty(value)){
                return URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("%", "%25").replace("_", "%5F");
            }else{
                return null;
            }
        } catch (Exception e) {
            throw new RuntimeException("Failed to encode the string", e);
        }
    }
}

使用示例: 

public AjaxResult<PageInfo<DataProject>> getList(DataProject dataProject, @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) {
        BeanUtils.copyProperties(QueryParameterUtils.convertStringData(dataProject),dataProject);
List<DataProject> dataProjectList = dataProjectService.selectList(dataProject,pageNum,pageSize);

 }

如对您有所帮助,请动动您发财的小手,点个赞吧!

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值