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

org.zodiac.autoconfigure.mybatisplus.MyBatisPlusSqlSessionFactoryCustomizer Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version
package org.zodiac.autoconfigure.mybatisplus;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.zodiac.commons.util.Colls;
import org.zodiac.commons.util.lang.Strings;
import org.zodiac.mybatis.exception.MyBatisException;
import org.zodiac.mybatis.handler.SmartEnumTypeHandler;
import org.zodiac.sdk.toolkit.constants.StringPool;

public class MyBatisPlusSqlSessionFactoryCustomizer {

    private String typeEnumsPackage;
    private SqlSessionFactory sqlSessionFactory;
    private ApplicationContext applicationContext;

    public MyBatisPlusSqlSessionFactoryCustomizer(String enumsPackage, SqlSessionFactory sqlSessionFactory,
        ApplicationContext applicationContext) {
        this.typeEnumsPackage = enumsPackage;
        this.sqlSessionFactory = sqlSessionFactory;
        this.applicationContext = applicationContext;
        List basePackage = Colls.list();
        if (Strings.isNotEmpty(this.typeEnumsPackage)) {
            basePackage.addAll(Arrays.asList(this.typeEnumsPackage.split(",")));
        } else {
            /*从注解中解析basePackage*/
            Map applicationClass =
                this.applicationContext.getBeansWithAnnotation(SpringBootApplication.class);
            applicationClass.forEach((k, v) -> {
                SpringBootApplication ann = AnnotationUtils.findAnnotation(v.getClass(), SpringBootApplication.class);
                if (ann.scanBasePackages().length == 0 && ann.scanBasePackageClasses().length == 0) {
                    basePackage.add(v.getClass().getPackage().getName());
                } else {
                    basePackage.addAll(Arrays.asList(ann.scanBasePackages()));
                    basePackage.addAll(Arrays.asList(ann.scanBasePackageClasses()).stream()
                        .map(s -> s.getPackage().getName()).collect(Collectors.toList()));
                }
            });
            List newPackage =
                basePackage.stream().map(s -> s.endsWith("*") ? s : s + ".**").collect(Collectors.toList());
            basePackage.clear();
            basePackage.addAll(newPackage);
        }
        this.typeEnumsPackage = basePackage.stream().collect(Collectors.joining(","));
        if (Strings.notBlank(this.typeEnumsPackage)) {
//            Set classes;
//            if (null != typeEnumsPackage && typeEnumsPackage.contains(StringPool.STAR) && !typeEnumsPackage.contains(StringPool.COMMA)
//                && !typeEnumsPackage.contains(StringPool.SEMICOLON)) {
//                classes = PackageHelper.scanTypePackage(typeEnumsPackage);
//            } else {
//                String[] typeEnumsPackageArray = StringUtils.tokenizeToStringArray(this.typeEnumsPackage,
//                    ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
//                Assert.notNull(typeEnumsPackageArray, String.format("Not find typeEnumsPackage: %s .", this.typeEnumsPackage));
//                classes = new HashSet<>();
//                for (String typePackage : typeEnumsPackageArray) {
//                    Set scanTypePackage = PackageHelper.scanTypePackage(typePackage);
//                    if (scanTypePackage.isEmpty()) {
//                    } else {
//                        classes.addAll(PackageHelper.scanTypePackage(typePackage));
//                    }
//                }
//            }
//            /*取得类型转换注册器*/
//            TypeHandlerRegistry typeHandlerRegistry = this.sqlSessionFactory.getConfiguration().getTypeHandlerRegistry();
//            for (Class cls : classes) {
//                if (cls.isEnum()) {
//                    /*原生方式*/
//                    registerOriginalEnumTypeHandler(typeHandlerRegistry, cls);
//                }
//            }
            Set classes;
            if (this.typeEnumsPackage.contains(StringPool.STAR) && !this.typeEnumsPackage.contains(StringPool.COMMA)
                && !this.typeEnumsPackage.contains(StringPool.SEMICOLON)) {
                classes = PackageHelper.scanTypePackage(this.typeEnumsPackage);
            } else {
                String[] typeEnumsPackageArray = StringUtils.tokenizeToStringArray(this.typeEnumsPackage,
                    ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
                Assert.notNull(typeEnumsPackageArray, String.format("Not find typeEnumsPackage: %s .", this.typeEnumsPackage));
                classes = Colls.set();
                for (String typePackage : typeEnumsPackageArray) {
                    Set scanTypePackage = PackageHelper.scanTypePackage(typePackage);
                    if (scanTypePackage.isEmpty()) {
                    } else {
                        classes.addAll(PackageHelper.scanTypePackage(typePackage));
                    }
                }
            }
            /*取得类型转换注册器*/
            TypeHandlerRegistry typeHandlerRegistry = this.sqlSessionFactory.getConfiguration().getTypeHandlerRegistry();
            for (Class cls : classes) {
                if (cls.isEnum()) {
                    /*原生方式*/
                    registerOriginalEnumTypeHandler(typeHandlerRegistry, cls);
                }
            }
        }
    }

    protected void registerOriginalEnumTypeHandler(TypeHandlerRegistry typeHandlerRegistry, Class enumClazz) {
        typeHandlerRegistry.register(enumClazz, SmartEnumTypeHandler.class);
    }

    static class PackageHelper {

        /**
         * 别名通配符设置。
         * 

* >property name="typeAliasesPackage" value="com.baomidou.*.entity"/> *

* * @param typeAliasesPackage 类别名包路径 * @return 包名称列表 */ public static String[] convertTypeAliasesPackage(String typeAliasesPackage) { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); String pkg = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(typeAliasesPackage) + "/*.class"; /* * 将加载多个绝对匹配的所有Resource * 将首先通过ClassLoader.getResource("META-INF")加载非模式路径部分,然后进行遍历模式匹配,排除重复包路径 */ try { Set set = Colls.set(); Resource[] resources = resolver.getResources(pkg); if (resources != null && resources.length > 0) { MetadataReader metadataReader; for (Resource resource : resources) { if (resource.isReadable()) { metadataReader = metadataReaderFactory.getMetadataReader(resource); set.add( Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); } } } if (!set.isEmpty()) { return set.toArray(new String[] {}); } return new String[0]; } catch (Exception e) { throw new MyBatisException(String.format("Not find typeAliasesPackage: %s", pkg), e); } } /** * 扫描获取指定包路径所有类。 * * @param typePackage 扫描类包路径,多个用{@code ,}分割 * @return 类集合 */ public static Set scanTypePackage(String typePackage) { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); String pkg = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(typePackage) + "/*.class"; /* * 将加载多个绝对匹配的所有Resource * 将首先通过ClassLoader.getResource("META-INF")加载非模式路径部分,然后进行遍历模式匹配,排除重复包路径 */ try { Set set = Colls.set(); Resource[] resources = resolver.getResources(pkg); if (resources != null && resources.length > 0) { MetadataReader metadataReader; for (Resource resource : resources) { if (resource.isReadable()) { metadataReader = metadataReaderFactory.getMetadataReader(resource); set.add(Class.forName(metadataReader.getClassMetadata().getClassName())); } } } return set; } catch (Exception e) { throw new MyBatisException(String.format("Not find scanTypePackage: %s", pkg), e); } } /** * 新建文件目录。 * * @param file 文件 */ public static void mkDir(File file) { if (file.getParentFile().exists()) { file.mkdir(); } else { mkDir(file.getParentFile()); file.mkdir(); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy