SpringBoot多数据源自定义配置
不瑶碧莲 人气:2在开发中我们有可能会遇到一个项目需要配置多个数据源,或者需要读写分离的配置,在启动类上贴上@MapperScan注解指定扫描对应的mapper.xml文件肯迪那个是无法满足了。我们可以通过自定义配置数据库配置类来解决这个问题,方式有很多,不同的业务采用的方式也不同,下面我简单的介绍我们项目的使用的方法
比如:项目中我需要连接opretion和device这个两个数据库,且需要进行读写分离,在配置文件中如下:
针对device库我们先创建一个数据库连接配置类
@Configuration @MapperScan(basePackages = {"com.liuqing.my.repo.device"}, sqlSessionTemplateRef = "deviceSqlSessionTemplate") public class DeviceDSConfig { @Value("${props.sql.show}") //定义在配置文件中的字段 ture private String sqlShow; }
@MapperScan
basePackages = {"com.liuqing.my.repo.device"}
指定包扫描
sqlSessionTemplateRef = "deviceSqlSessionTemplate")
指定sqlSessionTemplateRef
在类中添加配置文件中的读写数据源
@ConfigurationProperties(prefix = "spring.shardingsphere.datasource.device.read") public DataSource deviceReadDataSource() { return new DruidDataSource(); } @Bean @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.device.write") public DataSource deviceWriteDataSource() { return new DruidDataSource(); }
@ConfigurationProperties
注解的作用和@Value类似,都是获取配置文件中相应的配置值,但是@ConfigurationProperties与@Value不同的是,@Value一次只能获取一个值,但是@ConfigurationProperties可以获取多个值,此处可以将配置文件中的属性,自动封装到DruidDataSource
的属性中
配置Sharding数据源的Bean,也就是device.read
和device.write
读写分离的数据源
通过@Qualifier注解来指定我们想要使用 deviceReadDataSource
方法返回的 bean ,即获取deviceReadDataSource
方法返回DruidDataSource对象,deviceWriteDataSource
同理。
通过LoadBalanceStrategyConfiguration
是实现我们负载均衡策略
通过MasterSlaveRuleConfiguration
构造方法实现自定义的负载均衡算法
@Bean public DataSource deviceShardingDataSource(@Qualifier("deviceReadDataSource") DataSource readDataSource, //指定使用deviceReadDataSource的Bean返回的readDataSource对象 @Qualifier("deviceWriteDataSource") DataSource writeDataSource) throws SQLException { Map<String, DataSource> dataSourceMap = new HashMap<>(); dataSourceMap.put("device-read", readDataSource); dataSourceMap.put("device-write", writeDataSource); //Spring负载均衡自动配置类 LoadBalanceStrategyConfiguration LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration = new LoadBalanceStrategyConfiguration("round_robin"); //负载均衡算法 MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration( "device_read_write", "device-write", Lists.newArrayList("device-read"), loadBalanceStrategyConfiguration); Properties properties = new Properties(); properties.setProperty("sql.show", sqlShow); return MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, masterSlaveRuleConfig, properties); //返回一个DataSource }
创建返回SqlSessionFactory的Bean
1、创建MybatisSqlSessionFactoryBean
对象配置SqlSessionFactory;
2、创建MybatisConfiguration
对象调用setMapUnderscoreToCamelCase方法,开启mapUnderscoreToCamelCase配置驼峰转换
3、创建GlobalConfig
对象出传入MybatisConfiguration对象设置关闭对应banner(可以选择不关,但是利于查看日志和控制台)
4、通过ResourcePatternResolver
资源模式解析器,配置mapper.xml的文件路径
@Bean @Primary //在同样的DataSource中,首先使用被标注的SqlSessionFactory public SqlSessionFactory deviceSqlSessionFactory(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) { MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean(); bean.setDataSource(shardingDataSource); //设置 MybatisSqlSessionFactory的数据源 //MyBatis开启mapUnderscoreToCamelCase配置驼峰转换 MybatisConfiguration configuration = new MybatisConfiguration(); configuration.setMapUnderscoreToCamelCase(true); GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration); globalConfig.setBanner(false); //关闭Mybatis 加载的banner bean.setGlobalConfig(globalConfig); bean.setConfiguration(configuration); // 添加XML目录 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //资源模式解析器 try { bean.setMapperLocations(resolver.getResources("classpath:mapper/device/**/*Mapper.xml")); //设施设置mapper映射器位置 return bean.getObject(); //返回一个SqlSessionFactory'po } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } }
题外话:默认情况下,
@Autowired
按类型装配 Spring Bean。如果容器中有多个相同类型的 bean,则框架将抛出NoUniqueBeanDefinitionException
, 以提示有多个满足条件的 bean 进行自动装配。程序无法正确做出判断使用哪一个,所以会报错,可以使用@Primary和@Qualifier注解类解决这类问题
- 通过将
@Qualifier
注解与我们想要使用的特定 Spring bean 的名称一起进行装配,Spring 框架就能从多个相同类型并满足装配要求的 bean 中找到我们想要的@Primary
的解,可以用来发生依赖注入的歧义时决定要注入哪个 bean。当存在多个相同类型的 bean 时,此注解定义了Bean的首选项。简单来说就是@Qualifier注解那多个Bean指定了我要那个Bean,而@Primary注解表示那个多个Bean,先选贴了@Primary注解的Bean
创建SqlSessionTemplate的Bean
方法名要与类名上@MapperScan注解中的sqlSessionTemplateRef属性值一致;否者无法映射
SqlSessionTemplate是MyBatis-Spring的核心。这个类负责管理MyBatis的SqlSession,调用MyBatis的SQL方法,翻译异常。SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用。
@Bean @Primary public SqlSessionTemplate deviceSqlSessionTemplate(@Qualifier("deviceSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); }
创建DataSourceTransactionManager 事务管理器
@Bean @Primary public DataSourceTransactionManager deviceTransactionManager(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) { return new DataSourceTransactionManager(shardingDataSource); }
到此,我们的配置基本结束,根据我们配置的mapper包扫描下创建对应的mapper接口,
在resource目录下根据我们在配置类中配置的路径存放即可;
最后
注意:这是一个数据源的案例,当是需要配置多个数据源的时候,流程是一样的
1.在配置文件中配置数据库连接数据
2.创建配置类
3.创建mapper接口和mapper.xml文件
加载全部内容