All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.yulichang.wrapper.resultmap.MybatisLabelFree Maven / Gradle / Ivy

There is a newer version: 1.5.2
Show newest version
package com.github.yulichang.wrapper.resultmap;

import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.segments.SelectCache;
import lombok.Getter;

import java.util.*;
import java.util.function.Predicate;

/**
 * 无泛型约束 实现自由映射
 *
 * @author yulichang
 * @since 1.4.4
 */
@Getter
public class MybatisLabelFree implements Label {

    private String property;

    private Class javaType;

    private Class ofType;

    private List resultList;

    /**
     * wrapper里面的引用
     */
    private List> mybatisLabels;

    private MybatisLabelFree() {
    }

    @SuppressWarnings({"unused", "unchecked", "DuplicatedCode"})
    public static class Builder {

        private final MybatisLabelFree mybatisLabel;

        /**
         * 手动构建
         *
         * @param property property
         * @param javaType javaType
         * @param ofType   映射类
         */
        public Builder(String property, Class javaType, Class ofType) {
            this.mybatisLabel = new MybatisLabelFree<>();
            mybatisLabel.property = property;
            mybatisLabel.javaType = javaType;
            mybatisLabel.ofType = ofType;
            mybatisLabel.resultList = new ResultList();
            mybatisLabel.mybatisLabels = new ArrayList<>();
        }

        public  Builder all(Class entityClass) {
            allBuild(null, entityClass);
            return this;
        }

        public  Builder all(String prefix, Class entityClass) {
            allBuild(prefix, entityClass);
            return this;
        }

        /**
         * 映射实体字段过滤(含主键)
         */
        public  Builder filter(Class entityClass, Predicate predicate) {
            Map fieldMap = MPJReflectionKit.getFieldMap(mybatisLabel.ofType);
            ColumnCache.getListField(entityClass).stream().filter(predicate)
                    .filter(p -> fieldMap.containsKey(p.getColumProperty())).forEach(c ->
                            mybatisLabel.resultList.add(new Result.Builder(false, null, c).build()));
            return this;
        }

        /**
         * 映射实体字段过滤(含主键)
         */
        public  Builder filter(String prefix, Class entityClass, Predicate predicate) {
            Map fieldMap = MPJReflectionKit.getFieldMap(mybatisLabel.ofType);
            ColumnCache.getListField(entityClass).stream().filter(predicate)
                    .filter(p -> fieldMap.containsKey(p.getColumProperty())).forEach(c ->
                            mybatisLabel.resultList.add(new Result.Builder(false, prefix, c).build()));
            return this;
        }

        public  Builder id(SFunction entity, SFunction tag) {
            Result.Builder builder = new Result.Builder<>(true, null);
            builder.column(entity).property(tag);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public  Builder id(SFunction entity) {
            Result.Builder builder = new Result.Builder<>(true, null);
            builder.column(entity);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public  Builder id(String index, SFunction entity, SFunction tag) {
            Result.Builder builder = new Result.Builder<>(true, index);
            builder.column(entity).property(tag);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public  Builder id(String index, SFunction entity) {
            Result.Builder builder = new Result.Builder<>(true, index);
            builder.column(entity);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public  Builder result(SFunction entity, SFunction tag) {
            Result.Builder builder = new Result.Builder<>(false, null);
            builder.column(entity).property(tag);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public  Builder result(SFunction entity) {
            Result.Builder builder = new Result.Builder<>(false, null);
            builder.column(entity);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public  Builder result(String index, SFunction entity, SFunction tag) {
            Result.Builder builder = new Result.Builder<>(false, index);
            builder.column(entity).property(tag);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public  Builder result(String index, SFunction entity) {
            Result.Builder builder = new Result.Builder<>(false, index);
            builder.column(entity);
            mybatisLabel.resultList.add(builder.build());
            return this;
        }

        public > Builder collection(Class entityClass, SFunction func) {
            return collection(null, entityClass, func);
        }

        /**
         * 嵌套
         */
        public > Builder collection(String prefix, Class entityClass, SFunction func) {
            String dtoFieldName = LambdaUtils.getName(func);
            Class dtoClass = LambdaUtils.getEntityClass(func);
            Map fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
            FieldCache field = fieldMap.get(dtoFieldName);
            Class genericType = MPJReflectionKit.getGenericType(field.getField());
            MybatisLabel.Builder builder;
            if (genericType == null || genericType.isAssignableFrom(entityClass)) {
                //找不到集合泛型 List List List , 直接查询数据库实体
                builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, entityClass, field.getType());
            } else {
                Class ofType = (Class) genericType;
                builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, entityClass, field.getType(), ofType, true);
            }
            mybatisLabel.mybatisLabels.add(builder.build());
            return this;
        }

        public > Builder collection(Class entityClass, SFunction func, MFunc> mFunc) {
            return collection(null, entityClass, func, mFunc);
        }

        public > Builder collection(SFunction func,
                                                                     MFunc> mFunc) {
            String dtoFieldName = LambdaUtils.getName(func);
            Class dtoClass = LambdaUtils.getEntityClass(func);
            FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
            //获取集合泛型
            Class genericType = MPJReflectionKit.getGenericType(field.getField());
            Class ofType = (Class) genericType;
            MybatisLabelFree.Builder builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), ofType);
            mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
            return this;
        }

        /**
         * 嵌套
         */
        public > Builder collection(String prefix,
                                                                     Class entityClass,
                                                                     SFunction func,
                                                                     MFunc> mFunc) {
            String dtoFieldName = LambdaUtils.getName(func);
            Class dtoClass = LambdaUtils.getEntityClass(func);
            FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
            //获取集合泛型
            Class genericType = MPJReflectionKit.getGenericType(field.getField());
            Class ofType = (Class) genericType;
            MybatisLabel.Builder builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, entityClass, field.getType(), ofType, false);
            mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
            return this;
        }

        public  Builder association(Class child, SFunction dtoField) {
            return association(null, child, dtoField);
        }

        /**
         * 嵌套
         */
        public  Builder association(String index, Class child, SFunction dtoField) {
            Class dtoClass = LambdaUtils.getEntityClass(dtoField);
            Map fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
            String dtoFieldName = LambdaUtils.getName(dtoField);
            FieldCache field = fieldMap.get(dtoFieldName);
            Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
            MybatisLabel.Builder builder;
            builder = new MybatisLabel.Builder<>(index, dtoFieldName, child, field.getType(), (Class) field.getType(), true);
            mybatisLabel.mybatisLabels.add(builder.build());
            return this;
        }

        public  Builder association(Class child, SFunction dtoField,
                                             MFunc> collection) {
            return association(null, child, dtoField, collection);
        }

        /**
         * 嵌套
         */
        public  Builder association(String index, Class child, SFunction dtoField,
                                             MFunc> collection) {
            String dtoFieldName = LambdaUtils.getName(dtoField);
            Class dtoClass = LambdaUtils.getEntityClass(dtoField);
            FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
            Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
            MybatisLabel.Builder builder = new MybatisLabel.Builder<>(index, dtoFieldName, child, field.getType(), (Class) field.getType(), false);
            mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
            return this;
        }

        public MybatisLabelFree build() {
            if (CollectionUtils.isEmpty(mybatisLabel.resultList)) {
                TableInfo tableInfo = TableHelper.get(mybatisLabel.ofType);
                Assert.notNull(tableInfo,
                        "无法自动映射, 找不到 <%s> 对应的表, 请使用 .all(xxx.class), id()或者result() 手动映射",
                        mybatisLabel.ofType.getSimpleName());
                all(mybatisLabel.ofType);
            }
            return mybatisLabel;
        }

        private void allBuild(String prefix, Class entityClass) {
            Map tagMap = MPJReflectionKit.getFieldMap(mybatisLabel.getOfType());
            List listField = ColumnCache.getListField(entityClass);
            for (SelectCache s : listField) {
                FieldCache field = tagMap.get(s.getColumProperty());
                if (Objects.nonNull(field)) {
                    Result result = new Result();
                    result.setIndex(prefix);
                    result.setId(s.isPk());
                    result.setJavaType(field.getType());
                    result.setProperty(s.getColumProperty());
                    result.setSelectNormal(s);
                    mybatisLabel.resultList.add(result);
                }
            }
        }
    }
}