springboot多数据源配置遇到的一些问题

目录

项目场景

问题1

        原因分析

        解决方法

问题2

        原因分析

        解决方案

 问题3

        原因分析:

        解决方案:


项目场景

最近在项目上,老板要求把登录模块的相关代码抽取出来,作为一个单独的security-login.jar使用,一开始觉得很简单只是移动代码就可以了,结果纸上谈来终觉浅。


问题1

security-login中需要扫描登录相关对应的mapper的xml文件,但在应用中集成了security-login.jar后发现加载不到这几个xml

@Configuration
@ConfigurationProperties(prefix = "spring.datasource.security.hikari")
public class SecurityLoginDataSourceConfig extends HikariConfig {

    @Bean(name="securityDataSource")
    public DataSource dataSource() {
        return new HikariDataSource(this);
    }

    @Bean(name = "securityTransactionManager")
    public PlatformTransactionManager platformTransactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

}


@Configuration
@MapperScan(basePackages = {"com.security.login.persistence.dao"},sqlSessionFactoryRef = "securitySessionFactory")
public class SecurityMyBatisConfig {

    @Bean
    public SqlSessionFactory securitySessionFactory(@Qualifier("securityDataSource") DataSource securityDataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean  = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(securityDataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/login/*.xml"));
        return sqlSessionFactoryBean.getObject();
    }

}

原因分析

应该时mapper locations没有被扫描到,导致sqlSessionFactoryBean构造的mapper少了

解决方法

将 "classpath:mapper/login/*.xml" 改为"classpath*:mapper/login/*.xml"

原因是两个配置有一点差别,classpath:只会到你的class路径中查找找文件。 classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找

问题2

如上代码当业务模块集成了security-login.jar模块后,进行数据库写入操作时报如下错误

RuntimeException occurred:No qualifying bean of type 'org.springframework.transaction.TransactionManager' available:
expected single matching bean but found 2: platformTransactionManager,securityTransactionManager"

原因分析

在sqlSessionFactory绑定时并没有指定transactionManager,因为项目中发现了两个实现,spring并不知道应该使用哪一个


解决方案

解决办法应该有两个方法

方法1:在定义transactionManager的地方指定primary bean

方法2:  在@Transactional注解中指定使用哪个transactionManager

@Configuration
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public class DatabaseConfig extends HikariConfig {
    @Primary
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(this);
    }

    @Primary
    @Bean
    public PlatformTransactionManager platformTransactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

}

 问题3

如上代码当业务模块集成了security-login.jar模块后,发现有两个功能不正常,一个是看起来正常的查询语句无法映射对应的PO中,另一个是发现分页插件不起做了,伪代码如下:

<select id="queryList"
            parameterType="com.test.po.UserPO"
            resultType="com.test.po.UserPO">
        SELECT
            us.user_name,
            us.user_sex
        FROM user us
</select>

原因分析

配置文件中mybatis.configuration.map-underscore-to-camel-case=true这个属性不生效了该属性的作用是mybatis在解析mapper的resultType时将column name与驼峰命名的PO进行映射(但是最佳实践应该是自定义一个resultMap做好column与PO之间的映射关系),看了一下源码发现在自定义了sqlSessionFactoryBean之后相关的一些参数并没有给设置,等于都走了默认值,并且plugins都没有设置如:分页拦截器等


解决方案

@Configuration
@MapperScan(value = {"com.test.dao"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class MybatisConfig {

    @Value("${mybatis.mapper-locations}")
    private String mapperLocations;

    @Value("${mybatis.type-aliases-package}")
    private String aliasesPackage;


    //使得mybatis.configuration开头的相关配置能够注入进来
    @Bean
    @ConfigurationProperties(prefix = "mybatis.configuration")
    public org.apache.ibatis.session.Configuration configuration() {
        return new org.apache.ibatis.session.Configuration();
    }

    @Primary
    @Bean
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource, org.apache.ibatis.session.Configuration configuration, PageInterceptor pageInterceptor) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean  = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageInterceptor});
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
        sqlSessionFactoryBean.setConfiguration(configuration);//手动设置configuration
        sqlSessionFactoryBean.setTypeAliasesPackage(aliasesPackage);
        return sqlSessionFactoryBean.getObject();
    }

}

总结

道虽迩,不行不至;事虽小,不为不成;纸上谈来终觉浅,绝知此事要躬行。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值