【createWrapper】根据条件类创建查询wrapper

前几天写一个有几十个字段的查询wrapper,写得我心烦意乱。然后就琢磨了一下能不能只传一个条件类对像就能创建对应的wrapper。去看了下mybatis-plus的文档没看到合适的api,有一个创建wrapper时传入实体类的,但那个的查询条件都是eq不太使用。所以我就自己用反射和泛型写了一个创建wrapper的方法,可以根据传入的dto对象和泛型来返回对应的wrapper。

理一下需求:
  1. 我需要一个能创建任意类型wrapper的方法。
  2. 这个方法的参数需要是Object类型,方便传入任意类型的dto。
  3. 能根据这个dto的字段类型来使用不同的查询条件。

大概思路就是根据泛型创建一个对应类型的QueryWrapper,使用反射来读取遍历dto的属性来作为查询条件。

实现

 public static <T> QueryWrapper<T> createWrapper(Object dto){
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        Class<?> dataClass = data.getClass();

        try {
            for (Field field : dataClass.getDeclaredFields()) {
                //如果属性没有用private修饰的话这行可以不用
                field.setAccessible(true);
                //获取字段类型和字段值
                Class<?> type = field.getType();
                Object value = field.get(data);
                if (value == null){
                    continue;
                }
                //将字段名转为数据库中的字段名
                String fieldName;
                //获取一下属性上的@TableField注解,优先使用注解的value作为字段名
                TableField tableFieldAnnotation = field.getAnnotation(TableField.class);
                if (tableFieldAnnotation != null) {
                    fieldName = tableFieldAnnotation.value();
                }else{
                //若没有TableField注解则将获取到的字段名转换一下,从驼峰命名改为下划线的形式
                    fieldName = convertToSnakeCase(field.getName());
                }
                //下面这部分定义字段的查询方式就看各自的习惯了,下面是我经常用的
                //根据字段的类型来选择不同的查询方式
                if (type == String.class) {
                    wrapper.like(fieldName, value);
                }else if (type == Long.class){
                    wrapper.eq(fieldName, value);
                }else if (type == List.class){
                    wrapper.in(fieldName, (ArrayList<?>)value);
                }else if (type == TimeParam.class){
                    TimeUtils val= (TimeParam)value;
                    wrapper.between(fieldName, val.getStart(), val.getEnd());
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return wrapper;

}  


    /**
     * 将驼峰命名法的字段名转为下划线隔开的形式
     * @param input
     * @return
     */
    public static String convertToSnakeCase(String input) {
        StringBuilder output = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);
            if (Character.isUpperCase(ch)) {
                if (i > 0) {
                    output.append(StrPool.C_UNDERLINE);
                }
                output.append(Character.toLowerCase(ch));
            } else {
                output.append(ch);
            }
        }
        return output.toString();
    }

欧了,希望这个方法能帮到各位

你可能感兴趣的:(java,mybatis)