關於Mybatis實體別名支持通配符掃描問題小結

Mybatis簡介

MyBatis 是一款優秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。

MyBatis 避免瞭幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。

MyBatis 可以使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄

問題

Spring集成Mybatis的項目中,可以為指定包下的實體取別名,這樣在Mapper xml文件中可以省略實體類的全路徑名稱,隻寫類名稱即可;但是在多模塊項目中,可能需要將實體放在不同的模塊下,此時需要配置多路徑掃描;

方式一:配置多個路徑,逗號分隔符隔開

	<!-- sqlSessionFactory spring 整合 mybatis -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    	<property name="dataSource" ref="dataSource" />
    	<!-- mybatis 核心配置 -->
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
        <!-- mapper xml -->
        <property name="mapperLocations">
        	<array>
        		<value>classpath*:mybatis/mapper/*.xml</value>
        	</array>
        </property>
        <!-- 實體類別名 多個路徑掃描 -->
        <property name="typeAliasesPackage" value="com.dongzz.cms.modules.a.entity,com.dongzz.cms.modules.b.entity" />
    </bean>

方式二:采用通配符的方式配置,默認不支持此方式,需要對 SqlSessionFactoryBean 進行重寫,使其支持通配符掃描

package com.dongzz.cms.common.plugin.mybatis;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.ClassUtils;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * 自定義 SqlSessionFactoryBean
 */
public class SqlSessionFactoryBean extends org.mybatis.spring.SqlSessionFactoryBean {

    public static final Logger logger = LoggerFactory.getLogger(SqlSessionFactoryBean.class);

    public static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; //  別名通配符

    /**
     * 重寫 實體別名擴展 支持通配符
     *
     * @param typeAliasesPackage 格式: com.dongzz.cms.modules.**.entity
     */
    @Override
    public void setTypeAliasesPackage(String typeAliasesPackage) {
        // 資源路徑解析器
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        // 元數據讀取
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
        // 解析路徑
        typeAliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(typeAliasesPackage) + "/" + DEFAULT_RESOURCE_PATTERN;
        logger.debug("別名包通配符:" + typeAliasesPackage);
        try {
            Set<String> result = new HashSet<>(); // 別名包路徑集合
            Resource[] resources = resolver.getResources(typeAliasesPackage); // 根據路徑 讀取所有的類資源
            if (resources != null && resources.length > 0) {
                MetadataReader metadataReader = null;
                for (Resource resource : resources) {
                    if (resource.isReadable()) {
                        metadataReader = metadataReaderFactory.getMetadataReader(resource); // 讀取類的信息,每個 Resource 都是一個類資源
                        try {
                            result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); // 存儲類對應的包路徑
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            if (result.size() > 0) {
                logger.debug("別名包路徑集合:" + StringUtils.join(result.toArray(), ","));
                super.setTypeAliasesPackage(StringUtils.join(result.toArray(), ","));
            } else {
                logger.warn("Parameter typeAliasesPackage:" + typeAliasesPackage + ", not found any packages.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

Xml配置:

	<!-- sqlSessionFactory 采用自定義的 -->
	<bean id="sqlSessionFactory" class="com.dongzz.cms.common.plugin.mybatis.SqlSessionFactoryBean">
    	<property name="dataSource" ref="dataSource" />
    	<!-- mybatis 核心配置 -->
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
        <!-- mapper xml -->
        <property name="mapperLocations">
        	<array>
        		<value>classpath*:mybatis/mapper/*.xml</value>
        	</array>
        </property>
        <!-- 實體類別名 通配符掃描 -->
        <property name="typeAliasesPackage" value="com.dongzz.cms.modules.**.entity" />
    </bean>

通過自定義 SqlSessionFactoryBean 使得mybatis支持通配符別名掃描,這樣在多模塊項目中,掃描路徑僅需要配置一次即可;

到此這篇關於Mybatis實體別名支持通配符掃描的文章就介紹到這瞭,更多相關Mybatis通配符掃描內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: