tk.mybatis 使用注解实现动态配置查询条件(一)

       由于很多查询条件都有共性,而且都是重复的工作,所以自定义了注解,来实现动态查询的功能,这个是最简单的查询 ,后面有时间再扩展。主要用到以下的注解和相关的类(简单记录,后期再整理):

1、BaseQuery.class

@Data
public class BaseQuery {
    /**
     * 页码
     */
    private int pageNo = 1;
    /**
     * 每页行数
     */
    private int pageSize = 1000;
    /**
     * 排序字段
     */
    private String sort;
    /**
     * 排序方式
     */
    private String direction = "asc";
}

2、BaseMapper.class

public class BaseMapper<T> {
    /**
     * 领料单基本信息
     */
    @Autowired
    protected Mapper<T> mapper;
}

3、BaseForQuery.class


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

    /**
     * 获取没有特殊操作的查询条件
     *
     * @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;
        }
        // 排序
        BaseForQuery.setOrderBy(queryParams, example, hashMapDb);
        // 条件
        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 (fields == null || fields.length == 0 || Object.class.equals(queryParams)) {
            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 String name = field.getName();
            final Optional<String> optionalField = hashMapDb.keySet().stream()
                    .filter(n -> n.equalsIgnoreCase(name)).findAny();
            if (!optionalField.isPresent()) {
                continue;
            }
            final Condition condition = field.getAnnotation(Condition.class);
            if (condition == null) {
                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(name, value);
                    break;
                case "Like":
                    criteria.andLike(name, value.toString().concat("%"));
                    break;
                case "GreaterThan":
                    criteria.andGreaterThan(name, value);
                    break;
                case "GreaterThanOrEqualTo":
                    criteria.andGreaterThanOrEqualTo(name, value);
                    break;
                case "LessThan":
                    criteria.andLessThan(name, value);
                    break;
                case "LessThanOrEqualTo":
                    criteria.andLessThanOrEqualTo(name, value);
                    break;
                case "IsNotNull":
                    criteria.andIsNotNull(name);
                    break;
                case "IsNull":
                    criteria.andIsNull(name);
                    break;
                default:
                    break;
            }
        }

        BaseForQuery.getCondition(criteria, queryParams.getClass().getSuperclass(), 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();
            }
        }
    }
}

4、ResultInfo.class


@Data
public class ResultInfo<T,E> {
/**
* 列表数据
*/
    private T detail;

/**
* 总条数
*/
    private E summary;
}

5、BaseSummary.class


@Data
public class BaseSummary {

/**
* 总条数
*/
    private long totalRows;
}

 6、Condition.class

@Constraint(validatedBy = FullNameValidator.class)
@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;

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

7、ConditionEnum.class


public enum ConditionEnum {

    /**
     * 等于
     */
    Equals("Equals", "等于"),

    /**
     * 等于
     */
    Like("Like", "等于"),

    /**
     * 大于
     */
    GreaterThan("GreaterThan", "大于"),

    /**
     * 大于等于
     */
    GreaterThanOrEqualTo("GreaterThanOrEqualTo", "大于等于"),

    /**
     * 小于
     */
    LessThan("LessThan", "小于"),

    /**
     * 小于等于
     */
    LessThanOrEqualTo("LessThanOrEqualTo", "小于等于"),

    /**
     * 不为空
     */
    IsNotNull("IsNotNull", "不为空"),

    /**
     * 为空
     */
    IsNull("IsNull", "为空");

    /**
     * 构造函数
     *
     * @param key   键
     * @param value 值
     */
    ConditionEnum(final String key, final String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 键
     */
    private final String key;

    /**
     * 值
     */
    private final String value;

    /**
     * 获取 健
     *
     * @return 健
     */
    public String getKey() {
        return this.key;
    }

    /**
     * 获取 值
     *
     * @return 值
     */
    public String getValue() {
        return this.value;
    }
}

8、DataTypeEnum.class


public enum DataTypeEnum {

    /**
     * Integer
     */
    INTEGER(Integer.class, "Integer"),

    /**
     * Date
     */
    DATE(Date.class, "Date"),

    /**
     * Double
     */
    DOUBLE(Double.class, "Double"),

    /**
     * Float
     */
    FLOAT(Float.class, "Float"),

    /**
     * BigDecimal
     */
    BIGDECIMAL(BigDecimal.class, "BigDecimal"),

    /**
     * String
     */
    STRING(String.class, "String"),

    /**
     * Long
     */
    LONG(Long.class, "Long");

    /**
     * 构造函数
     *
     * @param key   键
     * @param value 值
     */
    DataTypeEnum(final Class key, final String value) {
        this.key = key;
        this.value = value;
    }

    /**
     * 键
     */
    private final Class key;

    /**
     * 值
     */
    private final String value;

    /**
     * 获取 健
     *
     * @return 健
     */
    public Class getKey() {
        return this.key;
    }

    /**
     * 获取 值
     *
     * @return 值
     */
    public String getValue() {
        return this.value;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38428623/article/details/103839364