如何解决Mybatis实体别名支持通配符扫描问题

发布时间:2022-01-21 09:42:50 作者:小新
来源:亿速云 阅读:175

小编给大家分享一下如何解决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实体别名支持通配符扫描问题”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

推荐阅读:
  1. springBoot mybatis包扫描问题怎么解决
  2. Mybatis映射实体怎么解决LocalDateTime格式转换问题

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mybatis

上一篇:Linux系统怎么安装设置MySQL

下一篇:plsql可不可以连接mysql

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》