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

com.github.yulichang.wrapper.resultmap.MybatisLabel 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.Asserts;
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;
import java.util.stream.Collectors;

/**
 * collection 标签 目前先支持这几个属性 后续在扩展
 *
 * @author yulichang
 * @since 1.3.0
 */
@Getter
public class MybatisLabel implements Label {

    private String index;

    private String property;

    private Class entityClass;

    private Class javaType;

    private Class ofType;

    private List resultList;

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

    private MybatisLabel() {
    }

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

        private final MybatisLabel mybatisLabel;

        /**
         * 自动构建
         */
        @SuppressWarnings("unchecked")
        public Builder(String index, String property, Class entityClass, Class javaType) {
            this.mybatisLabel = new MybatisLabel<>();
            mybatisLabel.property = property;
            mybatisLabel.index = index;
            mybatisLabel.entityClass = entityClass;
            mybatisLabel.javaType = javaType;
            mybatisLabel.ofType = (Class) entityClass;
            mybatisLabel.resultList = new ArrayList<>();
            mybatisLabel.mybatisLabels = new ArrayList<>();
            autoBuild(true, entityClass, (Class) entityClass);
        }

        /**
         * 手动构建
         *
         * @param property    property
         * @param entityClass 数据库实体类
         * @param javaType    javaType
         * @param ofType      映射类
         * @param auto        自动映射数据库实体对应的字段
         */
        public Builder(String index, String property, Class entityClass, Class javaType, Class ofType, boolean auto) {
            this.mybatisLabel = new MybatisLabel<>();
            mybatisLabel.property = property;
            mybatisLabel.index = index;
            mybatisLabel.entityClass = entityClass;
            mybatisLabel.javaType = javaType;
            mybatisLabel.ofType = ofType;
            mybatisLabel.resultList = new ArrayList<>();
            mybatisLabel.mybatisLabels = new ArrayList<>();
            autoBuild(auto, entityClass, ofType);
        }

        /**
         * 映射实体全部字段
         */
        public Builder all() {
            autoBuild(true, mybatisLabel.entityClass, mybatisLabel.ofType);
            return this;
        }

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

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

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

        public Builder result(SFunction entity) {
            Result.Builder builder = new Result.Builder<>(false, mybatisLabel.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 Builder<>(prefix, dtoFieldName, entityClass, field.getType());
            } else {
                Class ofType = (Class) genericType;
                builder = new 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(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 不支持集合类");
            MybatisLabelFree.Builder builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), (Class) field.getType());
            mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
            return this;
        }

        /**
         * 嵌套
         */
        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 MybatisLabel build() {
            if (CollectionUtils.isEmpty(mybatisLabel.resultList)) {
                autoBuild(true, mybatisLabel.entityClass, mybatisLabel.ofType);
            }
            return mybatisLabel;
        }

        private void autoBuild(boolean auto, Class entityClass, Class tagClass) {
            TableInfo tableInfo = TableHelper.get(entityClass);
            Asserts.hasTable(tableInfo, entityClass);
            Map tagMap = MPJReflectionKit.getFieldMap(tagClass);
            if (auto && !tagMap.isEmpty()) {
                List listField = ColumnCache.getListField(entityClass);
                if (entityClass.isAssignableFrom(tagClass)) {
                    mybatisLabel.resultList.addAll(listField.stream().map(i -> {
                        Result result = new Result();
                        result.setId(i.isPk());
                        result.setIndex(mybatisLabel.index);
                        result.setProperty(i.getColumProperty());
                        result.setJavaType(i.getColumnType());
                        result.setJdbcType(Objects.isNull(i.getTableFieldInfo()) ? null : i.getTableFieldInfo().getJdbcType());
                        result.setSelectNormal(i);
                        return result;
                    }).collect(Collectors.toList()));
                } else {
                    for (SelectCache s : listField) {
                        FieldCache field = tagMap.get(s.getColumProperty());
                        if (Objects.nonNull(field)) {
                            Result result = new Result();
                            result.setId(s.isPk());
                            result.setIndex(mybatisLabel.index);
                            result.setProperty(s.getColumProperty());
                            result.setJavaType(field.getType());
                            result.setSelectNormal(s);
                            mybatisLabel.resultList.add(result);
                        }
                    }
                }
            }
        }
    }
}