基于Mybatis-Plus进行查询封装

发布时间:2023年12月23日

基于Mybatis-Plus进行查询封装

package com.test.common.orm.builder;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.impl.PerpetualCache;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;



public final class QueryWrapperBuilder {


   private static final Cache FILED_CACHE = new PerpetualCache(IdUtil.simpleUUID());
   private static final Cache METHOD_CACHE = new PerpetualCache(IdUtil.simpleUUID());
   private static final char[] UPPER_CASE_CHAR_ARRAY = new char[26];

   static {
       UPPER_CASE_CHAR_ARRAY[0]='A';UPPER_CASE_CHAR_ARRAY[1]='B';UPPER_CASE_CHAR_ARRAY[2]='C';
       UPPER_CASE_CHAR_ARRAY[3]='D';UPPER_CASE_CHAR_ARRAY[4]='E';UPPER_CASE_CHAR_ARRAY[5]='F';
       UPPER_CASE_CHAR_ARRAY[6]='G';UPPER_CASE_CHAR_ARRAY[7]='H';UPPER_CASE_CHAR_ARRAY[8]='I';
       UPPER_CASE_CHAR_ARRAY[9]='J';UPPER_CASE_CHAR_ARRAY[10]='K';UPPER_CASE_CHAR_ARRAY[11]='L';
       UPPER_CASE_CHAR_ARRAY[12]='M';UPPER_CASE_CHAR_ARRAY[13]='N';UPPER_CASE_CHAR_ARRAY[14]='O';
       UPPER_CASE_CHAR_ARRAY[15]='P';UPPER_CASE_CHAR_ARRAY[16]='Q';UPPER_CASE_CHAR_ARRAY[17]='R';
       UPPER_CASE_CHAR_ARRAY[18]='S';UPPER_CASE_CHAR_ARRAY[19]='T';UPPER_CASE_CHAR_ARRAY[20]='U';
       UPPER_CASE_CHAR_ARRAY[21]='V';UPPER_CASE_CHAR_ARRAY[22]='W';UPPER_CASE_CHAR_ARRAY[23]='X';
       UPPER_CASE_CHAR_ARRAY[24]='Y';UPPER_CASE_CHAR_ARRAY[25]='Z';
   }

   public static <T>QueryWrapper<T> buildListWrapper(final Class<T> entityClass, final Object voObject, Integer... group) {
       Assert.isTrue(null != entityClass,"entityClass cannot be null");
       Assert.isTrue(null != voObject,"voObject cannot be null");
       if(group != null && group.length > 1) {
           throw new IllegalArgumentException("group cannot greater than one");
       }
       AtomicInteger defaultGroup = new AtomicInteger(-1);
       if(null == group || group.length <= 0) {
           defaultGroup.set(1);
       } else {
           defaultGroup.set(group[0]);
       }
       QueryWrapper<T> queryWrapper = new QueryWrapper<>();
       Class<?> voObjectClass = voObject.getClass();
       String voClassName = voObjectClass.getName();
       Field[] fields = (Field[]) FILED_CACHE.getObject(voClassName);
       if(null == fields) {
           fields = voObjectClass.getDeclaredFields();
           if(fields.length > 0) {
               FILED_CACHE.putObject(voClassName, fields);
           } else {
               throw new IllegalArgumentException("voObject [" + voClassName + "] not has fields");
           }
       }
       Stream<Field> stream = Arrays.stream(fields);
       stream.forEach(field -> {
           if(field.isAnnotationPresent(QueryOperation.class) || field.isAnnotationPresent(QueryOperations.class)) {
               String fieldName = field.getName();
               String columnName = fieldToColumnName(fieldName);
               Annotation[] annotations = field.getAnnotations();
               List<QueryOperation> list = new ArrayList<>();
               for(Annotation annotation : annotations) {
                   if(annotation instanceof QueryOperations) {
                       QueryOperation[] queryOperations = ((QueryOperations) annotation).value();
                       list.addAll(Arrays.asList(queryOperations));
                   } else if(annotation instanceof QueryOperation){
                       list.add((QueryOperation) annotation);
                   }
               }
               QueryOperation queryOperation =
                   list.stream().filter(annotation ->
                           annotation.group() == defaultGroup.get())
                       .findFirst().orElse(null);
               if(null != queryOperation) {
                   String annoColumnName = queryOperation.columnName();
                   if(StringUtils.hasText(annoColumnName)) {
                       columnName = annoColumnName;
                   }
                   QueryOperationType queryOperationType = queryOperation.value();
                   String methodName = fileNameToMethodName(fieldName,"get");
                   String key = voClassName + "@" + methodName;
                   Method method = (Method) METHOD_CACHE.getObject(key);
                   if(null == method) {
                       method = ReflectionUtils.findMethod(voObjectClass, methodName);
                       METHOD_CACHE.putObject(key,method);
                   }
                   Assert.notNull(method,"method : [ " + methodName + " ] not exists in class : [ " + voObjectClass.getName() + "]");
                   Object o = ReflectionUtils.invokeMethod(method, voObject);
                   setQueryWrapper(queryWrapper,queryOperationType,columnName,o);
               }
           }
       });
       return queryWrapper;
   }

   public static String fieldToColumnName(String fieldName) {
       Assert.isTrue(StringUtils.hasText(fieldName), "fieldName must contains at least one character");
       char[] chars = fieldName.toCharArray();
       List<Integer> indexList = new ArrayList<>();
       for(int i=0;i<chars.length;i++) {
           char val = chars[i];
           for(char charVal : UPPER_CASE_CHAR_ARRAY) {
               if(val == charVal) {
                   indexList.add(i);
                   break;
               }
           }
       }
       fieldName = fieldName.toLowerCase(Locale.ENGLISH);
       StringBuilder columnName = new StringBuilder(fieldName);
       indexList.forEach(index->{
           columnName.insert(index,"_");
       });
       return columnName.toString();
   }

   public static String fileNameToMethodName(final String fieldName,String prefix) {
       return prefix + fieldName.substring(0,1).toUpperCase(Locale.ENGLISH) + fieldName.substring(1);
   }

   private static void setQueryWrapper(QueryWrapper<?> queryWrapper, QueryOperationType queryOperationType,
                                       String columnName, Object o) {
       boolean canSet = false;
       if(o instanceof String) {
           canSet = StringUtils.hasLength((CharSequence)o) ;
       } else {
           canSet = null != o ;
       }

       if(canSet) {
           if(queryOperationType == QueryOperationType.EQUAL) {
               queryWrapper.eq(columnName,o);
           } else if(queryOperationType == QueryOperationType.NOT_EQUAL) {
               queryWrapper.ne(columnName,o);
           } else if(queryOperationType == QueryOperationType.LIKE) {
               queryWrapper.like(columnName,o);
           } else if(queryOperationType == QueryOperationType.BETWEEN) {
               if(!(o instanceof Collection<?>)) {
                   throw new UnsupportedOperationException("只对集合支持between操作");
               }
               if(((Collection<?>) o).size() < 2) {
                   throw new IllegalArgumentException("集合中元素的数量异常");
               }
               Object[] objArr = ((Collection<?>) o).toArray();
               queryWrapper.between(columnName, objArr[0], objArr[1]);
           } else if(queryOperationType == QueryOperationType.ORDER_ASC) {
               queryWrapper.orderByAsc(columnName);
           } else if(queryOperationType == QueryOperationType.ORDER_DESC) {
               queryWrapper.orderByDesc(columnName);
           }
       }
   }


   /**
    * 执行查询的类型
    * */
   @Target(ElementType.FIELD)
   @Retention(RetentionPolicy.RUNTIME)
   @Repeatable(QueryOperations.class)
   public @interface QueryOperation {

       QueryOperationType value() default QueryOperationType.EQUAL;

       int group() default 1;

       String columnName() default "";

   }

   /**
    * 设置可以使用重复注解
    * */
   @Target(ElementType.FIELD)
   @Retention(RetentionPolicy.RUNTIME)
   public @interface QueryOperations {
       QueryOperation[] value();
   }

   public enum QueryOperationType {
       EQUAL("equal"),NOT_EQUAL("not_equal"),LIKE("like"),BETWEEN("between"),ORDER_DESC("order_desc"),ORDER_ASC("order_asc");

       private final String operationType;

       QueryOperationType(String operationType) {
           this.operationType = operationType;
       }

   }




}

文章来源:https://blog.csdn.net/Beyourselfsun/article/details/135172238
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。