定制SqlSessionFactoryBean,扩展typeAliasesPackage配置

package com.oneplus.wms.mvc;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Set;

/**
 * 功能描述:Mybatis自动化扫描Model扩展
 * <p/>
 * WMS各个Model存放在不同的Package下, 当前需要支持:<package name="com.oneplus.wms.dao.model" />下所有子的配置
 * 避免配置文件过多, 此种配置会扫描配置包下的所有子包
 *
 * @author: Zhenbin.Li
 * Date: 16/2/14 Time: 16:43
 */
public class OneplusSqlSessionFactoryBean extends SqlSessionFactoryBean {

    /**
     * sl4j
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(OneplusSqlSessionFactoryBean.class);

    /**
     * scan file
     */
    protected static final String PATH_FILE = "file";

    /**
     * scan jar
     */
    protected static final String PATH_JAR = "jar";

    /**
     * file suffix
     */
    protected static final String PATH_CLASS = "class";

    /**
     * Packages to search for type aliases.
     *
     * @param typeAliasesPackage package to scan for domain objects
     * @since 1.0.1
     */
    @Override
    public void setTypeAliasesPackage(String typeAliasesPackage) {
        if (StringUtils.isBlank(typeAliasesPackage)) {
            super.setTypeAliasesPackage(typeAliasesPackage);
        }

        LOGGER.info("mybatis自动扫描Model路径:" + typeAliasesPackage);
        Set<String> allPackageAliases = scanAllPackageAliases(typeAliasesPackage);
        if (CollectionUtils.isEmpty(allPackageAliases)) {
            super.setTypeAliasesPackage(typeAliasesPackage);
        }

        LOGGER.debug("mybatis自动扫描Model的所有结果:" + allPackageAliases);
        String joinAliases = Joiner.on(",").join(allPackageAliases);
        super.setTypeAliasesPackage(joinAliases);

    }

    /**
     * 扫描配置文件包下的所有字包
     *
     * @param pack mybatis-config.xml配置扫描model路径
     *             <typeAliases>
     *             <package name="com.oneplus.wms.dao.model" />
     *             </typeAliases>
     * @return 配置路径下的所有子包
     */
    protected Set<String> scanAllPackageAliases(String pack) {
        // 是否循环搜索子包
        boolean recursive = true;
        // 包名字
        String packageName = pack;
        // 包名对应的路径名称
        String packageDirName = packageName.replace('.', '/');
        Enumeration<URL> dirs;

        Set<String> packageAliases = Sets.newLinkedHashSet();
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            while (dirs.hasMoreElements()) {
                URL url = dirs.nextElement();
                String protocol = url.getProtocol();
                if (StringUtils.equals(PATH_FILE, protocol)) {
                    String filePath = URLDecoder.decode(url.getFile(), Charsets.UTF_8.displayName());
                    listAllChildPackages(packageName, filePath, recursive, packageAliases);
                } else if (StringUtils.equals(PATH_JAR, protocol)) {
                    LOGGER.info(PATH_JAR + "类型的扫描");
                }
            }
        } catch (Exception e) {
            LOGGER.error("mybatis扫描配置路径异常, 配置路径:" + pack, e);
        }

        return packageAliases;
    }

    /**
     * 在package对应的路径下找到所有的child Package
     *
     * @param packageName    路径名称
     * @param filePath       文件路径
     * @param recursive      是否子目录
     * @param packageAliases 子目录名称
     */
    protected void listAllChildPackages(String packageName, String filePath, final boolean recursive, Set<String> packageAliases) {
        File dir = new File(filePath);
        if (!dir.exists() || !dir.isDirectory()) {
            return;
        }
        // 在给定的目录下找到所有的文件,并且进行条件过滤
        File[] dirFiles = dir.listFiles(new FileFilter() {

            @Override
            public boolean accept(File file) {
                // 接受dir目录
                boolean acceptDir = recursive && file.isDirectory();
                // 接受class文件
                boolean acceptClass = StringUtils.endsWith(file.getName(), PATH_CLASS);
                return acceptDir || acceptClass;
            }
        });

        for (File file : dirFiles) {
            if (file.isDirectory()) {
                listAllChildPackages(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, packageAliases);
            } else {
                packageAliases.add(file.getParent());
            }
        }
    }
}


你可能感兴趣的:(定制SqlSessionFactoryBean,扩展typeAliasesPackage配置)