JAVA general single table AND query operation

JAVA general single table AND query operation, first record it, there will be time to improve later. Only support single table public AND query

1. Annotation


@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Condition {

    /**
     * 默认为 等于
     *
     * @return 等于
     */
    ConditionEnum conditionEnum() default ConditionEnum.Equals;

    /**
     * 数据类型 默认 字符串
     *
     * @return 字符串
     */
    DataTypeEnum dataTypeEnum() default DataTypeEnum.STRING;

    /**
     * DO的属性名,默认和属性值一致
     *
     * @return DO的属性名
     */
    String fieldName() default "";

    /**
     * 格式
     *
     * @return 格式
     */
    String format() default "";
}

 

2. General AND query class for basic query


@Slf4j
public class BaseForQuery<T> extends BaseMapper<T> {

    /**
     * DESC
     */
    private final static String DESC = "desc";

    /**
     * 获取没有特殊操作的查询条件
     *
     * @param queryParams 查询的参数
     * @param entityObj   实体对象
     * @return 返回查询的对象
     */
    protected static <K extends BaseQuery, V> Example getExample(final K queryParams, final Class<V> entityObj) {
        final Example example = new Example(entityObj, false);
        if (queryParams == null) {
            return example;
        }
        // 数据库对象的字段
        final Map<String, Annotation[]> hashMapDb = FieldUtil.getFieldsAnnotations(entityObj);
        if (hashMapDb == null || CollectionUtils.isEmpty(hashMapDb.entrySet())) {
            return example;
        }
        // 排序
        if (!StringUtils.isEmpty(queryParams.getSort())) {
            if (DESC.equalsIgnoreCase(queryParams.getDirection())) {
                example.orderBy(queryParams.getSort()).desc();
            } else {
                example.orderBy(queryParams.getSort()).asc();
            }
        }
        // 条件
        BaseForQuery.getCondition(example, queryParams, hashMapDb);
        return example;
    }

    /**
     * 设置 条件
     *
     * @param example     条件
     * @param queryParams 请求参数
     * @param hashMapDb   数据库
     */
    private static <K extends BaseQuery> void getCondition(final Example example, final K queryParams,
                                                           final Map<String, Annotation[]> hashMapDb) {
        final Example.Criteria criteria = example.createCriteria();
        BaseForQuery.getCondition(criteria, queryParams, hashMapDb);
    }

    /**
     * 获取条件
     *
     * @param criteria  查询条件
     * @param hashMapDb 数据库字段
     */
    private static <K> void getCondition(final Example.Criteria criteria, final K queryParams
            , final Map<String, Annotation[]> hashMapDb) {
        final Field[] fields = queryParams.getClass().getDeclaredFields();
        if (Object.class.equals(queryParams) || Object.class.equals(queryParams.getClass())) {
            return;
        }
        Object superInstance = null;
        try {
            superInstance = queryParams.getClass().getSuperclass().newInstance();
        } catch (final InstantiationException e) {
            log.error("{}", e);
        } catch (final IllegalAccessException e) {
            log.error("{}", e);
        }
        BeanUtils.copyProperties(queryParams, superInstance);
        if (fields == null || fields.length == 0) {
            // 递归调用
            BaseForQuery.getCondition(criteria, superInstance, hashMapDb);
            return;
        }
        for (final Field field : fields) {
            // 获取字段对应的值
            Object value;
            try {
                field.setAccessible(true);
                value = field.get(queryParams);
            } catch (final IllegalAccessException e) {
                continue;
            }
            if (StringUtils.isEmpty(value)) {
                continue;
            }
            final Condition condition = field.getAnnotation(Condition.class);
            if (condition == null) {
                continue;
            }
            // 用数据库生成的字段名称,避免异常
            String fieldName = condition.fieldName();
            if (StringUtils.isEmpty(fieldName)) {
                fieldName = field.getName();
            }
            final String finalFieldName = fieldName;
            final Optional<String> optionalField = hashMapDb.keySet().stream()
                    .filter(n -> n.equalsIgnoreCase(finalFieldName)).findAny();
            if (!optionalField.isPresent()) {
                continue;
            }
            if (!StringUtils.isEmpty(condition.format()) && condition.dataTypeEnum().getKey() == Date.class) {
                value = Date.from(LocalDateTime.parse(value.toString(), DateTimeFormatter
                        .ofPattern(condition.format())).atZone(ZoneId.systemDefault()).toInstant());
            }
            switch (condition.conditionEnum().getKey()) {
                case "Equals":
                    criteria.andEqualTo(fieldName, value);
                    break;
                case "Like":
                    criteria.andLike(fieldName, String.format("%s%", value));
                    break;
                case "GreaterThan":
                    criteria.andGreaterThan(fieldName, value);
                    break;
                case "GreaterThanOrEqualTo":
                    criteria.andGreaterThanOrEqualTo(fieldName, value);
                    break;
                case "LessThan":
                    criteria.andLessThan(fieldName, value);
                    break;
                case "LessThanOrEqualTo":
                    criteria.andLessThanOrEqualTo(fieldName, value);
                    break;
                case "IsNotNull":
                    criteria.andIsNotNull(fieldName);
                    break;
                case "IsNull":
                    criteria.andIsNull(fieldName);
                    break;
                default:
                    break;
            }
        }
        // 递归调用
        BaseForQuery.getCondition(criteria, superInstance, hashMapDb);
    }

    /**
     * 排序
     *
     * @param queryParams 请求参数
     * @param example     查询条件
     * @param hashMapDb   数据库的字段
     * @param <K>         泛型
     */
    private static <K extends BaseQuery> void setOrderBy(final K queryParams, final Example example, final Map<String, Annotation[]> hashMapDb) {
        if (!StringUtils.isEmpty(queryParams.getSort())) {
            String sort = queryParams.getSort();
            final Optional<String> optionalField = hashMapDb.keySet().stream().filter(n ->
                    n.equalsIgnoreCase(queryParams.getSort())).findAny();
            if (optionalField.isPresent()) {
                // 获取属性对应的字段
                sort = optionalField.get();
                final Optional<Annotation> annotation = Arrays.stream(hashMapDb
                        .get(sort)).filter(n -> n instanceof Column).findAny();
                if (annotation.isPresent()) {
                    final Column column = (Column) annotation.get();
                    sort = column.name();
                }
            }
            if (StringUtils.isEmpty(queryParams.getDirection())) {
                example.setOrderByClause(sort);
            } else {
                example.setOrderByClause(sort.concat(" ").concat(queryParams.getDirection()));
            }
        }
    }

    /**
     * 获取总行数和查询的条件
     *
     * @param queryParams 查询的请求参数
     * @param entityObj   实体对象
     * @param <K>         查询的请求参数 泛型对象
     * @param <V>         实体对象 泛型对象
     * @return 返回总的行数
     */
    protected <K extends BaseQuery, V> ResultInfo<List<T>, BaseSummary> getPagerData(final K queryParams, final Class<V> entityObj) {
        final Example example = BaseForQuery.getExample(queryParams, entityObj);
        return this.getPagerData(queryParams, example);
    }

    /**
     * 获取总行数和查询的条件
     *
     * @param queryParams 查询的请求参数
     * @param example     查询条件Example
     * @param <K>         查询的请求参数 泛型对象
     * @return 返回总的行数
     */
    protected <K extends BaseQuery> ResultInfo<List<T>, BaseSummary> getPagerData(final K queryParams, final Example example) {
        final ResultInfo resultInfo = new ResultInfo();
        final int count = this.mapper.selectCountByExample(example);
        final BaseSummary baseSummary = new BaseSummary();
        baseSummary.setTotalRows(count);
        // 总条数
        resultInfo.setSummary(baseSummary);
        List<T> list = new ArrayList<>();
        if (baseSummary.getTotalRows() != 0) {
            // 明细数据
            final int pageNo = queryParams.getPageNo();
            final int pageSize = queryParams.getPageSize();
            final int offset = (pageNo - 1) * pageSize;
            final RowBounds rowBounds = new RowBounds(offset, pageSize);
            // 查询数据
            list = super.mapper.selectByExampleAndRowBounds(example, rowBounds);
        }
        resultInfo.setDetail(list);

        return resultInfo;
    }

    /**
     * 返回分页之后的数据
     *
     * @param k   带有分页的信息
     * @param lst 列表
     * @param <K> 泛型
     * @return 返回分页之后的数据
     */
    protected static <K extends BaseQuery, V> List<V> getLists(final K k, final List<V> lst) {
        final int beginIndex = (k.getPageNo() - 1) * k.getPageSize();
        int endIndex = k.getPageNo() * k.getPageSize();
        if (lst.size() < endIndex) {
            endIndex = lst.size();
        }
        return lst.subList(beginIndex, endIndex);
    }

    /**
     * 排序
     *
     * @param forQuery 查询条件
     * @param example  example
     */
    protected <T extends BaseQuery> void setExampleOrderBy(final T forQuery, final Example example) {
        if (!StringUtils.isEmpty(forQuery.getSort())) {
            if (!StringUtils.isEmpty(forQuery.getDirection()) && DESC.equalsIgnoreCase(forQuery.getDirection())) {
                example.orderBy(forQuery.getSort()).desc();
            } else {
                example.orderBy(forQuery.getSort()).asc();
            }
        }
    }
}

3. BaseMapper class

import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.common.Mapper;

public class BaseMapper<T> {

    /**
     * 基本信息
     */
    @Autowired
    protected Mapper<T> mapper;
}

 

 

Guess you like

Origin blog.csdn.net/qq_38428623/article/details/105234896