datagridview绑定数据源不显示_SpringBoot系列(13):解锁Mybatis多数据源的最简姿势...

正常情况下,一个应用一个数据库是标配,也是很多小伙伴在开发企业级应用时最为常见的做法;然而,出于某些特殊的情况,一个应用需要跨数据库实现不同的功能需求 也逐渐变得很普遍!本文,我们将分享介绍一种最为简单的、基于注解式(Java Config)的方式实现Mybatis多数据源的访问。

所谓多数据源,说白了,其实就是“在应用系统中访问多个数据库实现某些业务功能”的另一种诠释!目前一些开源的项目也采用了各种不同的方式实现了“多数据源”,常见的包括“基于Mybatis和Spring JDBC Tempalte数据源 混合实现多数据源”、“基于Mybatis和Spring AOP实现多数据源”;

第一种方式毕竟混合了两种实现方式,对于咱们程序员来讲,就意味着你既需要掌握Mybatis、也需要掌握Spring JDBC Template的编码实现DAO层的操作、访问;

对于第二种方式,有些小伙伴看到AOP可能有点退怯,而且事实上这种实现的过程,需要你在“访问、操作数据库的方法或者类上”额外添加某个注解,标明来源于那个数据源!

本文,我们将不介绍上面这两种,而是采用一种更为简单、便捷、纯粹基于Mybatis的方式来实现多数据源,实战完成过后,你会发现,这种方式实现起来确实很简单,很简洁,很爽,当然啦,一些包目录结构的规范还是需要遵循的,不要慌,问题不大!

废话不多讲,下面,我们就进入实战过程!

(1)既然是“多数据源”,那么得需要建立多个数据库,等待被访问。在这里,我们仍然沿用了“technology”数据库,并新建了一个新的数据库“sb_redis”(在里面建立了一张数据库表 sys_config),对该数据库表采用Mybatis逆向工程生成相应的Entity、Mapper、Mapper.xml即可。

相应的源代码、数据库大家检出来一看就行了!以下为该数据库表sys_config的DDL:

CREATE TABLE `sys_config` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '字典类型', `name` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '字典名称', `code` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '选项编码', `value` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '选项取值', `order_by` int(11) DEFAULT '1' COMMENT '排序', `is_active` tinyint(4) DEFAULT '1' COMMENT '是否有效(1=是;0=否)', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_type_code` (`type`,`code`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='字典配置表';

(2)在这里值得一提的是,“多数据源实战”也有一些要求,即“主数据源Primary”只能有一个,“从数据源Second…”可以有多个,类似于数据库集群的“Master-Slave”模式或者ZooKeeper集群的 “Leader-Follower”选举机制。

由于我们是采用“简单的Java Config注解式”来实现“Mybatis多数据源”的,故而我们需要对不同数据源所生成的Entity、Mapper、Mapper.xml放置在不同的包目录下,目的在于“扫描”时可以检测到相应的“数据源”对应着相应的“包目录下的实体以及操作接口”,如下图所示:

68e4a1f3e6db4ea5918a043ab8133a4d

(3)接下来,我们在config包下基于Java Config创建两个用于“注入数据源”的显示配置,一个是DataSourcePrimary、另一个是DataSourceSecond(如果还有第三个、第四个数据源,也是照着同样的套路新建即可)。

当然啦,在手动显示注入数据源配置之前,需要在配置文件application.properties中加入相应数据库的链接配置,如下图所示:

525a873846554f028053522b9a193a91

(4)接着是主数据源DataSourcePrimary的显示配置:

/**主数据源 * @Author:debug (SteadyJack) * @Link: weixin-> debug0868 qq-> 1948831260 * @Date: 2019/11/7 9:57 **/ @Configuration @MapperScan(basePackages = "com.debug.springboot.model.mapper.primary",sqlSessionTemplateRef = "primarySqlSessionTemplate") public class DataSourcePrimary { @Autowired private Environment env; //数据源实例配置 @Primary @Bean(name = "primaryDataSource") //@ConfigurationProperties(prefix = "datasource.one") public DataSource dataSource(){ return DataSourceBuilder.create() .driverClassName(env.getProperty("datasource.one.driver")) .url(env.getProperty("datasource.one.url")) .username(env.getProperty("datasource.one.username")) .password(env.getProperty("datasource.one.password")) .build(); } @Primary @Bean(name = "primarySqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception{ SqlSessionFactoryBean bean=new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/primary/*.xml")); return bean.getObject(); } @Primary @Bean(name = "primaryTransactionManager") public DataSourceTransactionManager transactionManager(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception{ return new DataSourceTransactionManager(dataSource); } @Primary @Bean(name = "primarySqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory)throws Exception{ return new SqlSessionTemplate(sqlSessionFactory); }}


从上述该代码中,可以看出我们是一步步注入DataSource实例、SqlSessionFactory实例以及事务配置我SqlSession的操作模板实例(这些配置大家也可以采用Mybatis的XML配置文件来实现!)

同时,有一点需要注意,我们必须得对该数据源配置标注为“主数据源Primary”,通过@Primary实现即可!

而且,该主数据源指定了,com.debug.springboot.model.mapper.primary 包目录结构下的操作Mapper将操作主数据源“technology数据库”,对应着相应的Mapper.xml,即:

作Mapper将操作主数据源“technology数据库”,对应着相应的Mapper.xml,即:

new PathMatchingResourcePatternResolver().getResources("classpath:mappers/primary/*.xml")

(5)从数据源的显示Java Config配置跟主数据源的配置其实没多大区别,只需要去掉@primary注解以及调整相应的Mapper和Mapper.xml所在的包目录!完整的源代码如下所示:

/**从数据源 * @Author:debug (SteadyJack) * @Link: weixin-> debug0868 qq-> 1948831260 * @Date: 2019/11/7 9:57 **/@Configuration@MapperScan(basePackages = "com.debug.springboot.model.mapper.second",sqlSessionTemplateRef = "secondSqlSessionTemplate")public class DataSourceSecond { @Autowired private Environment env; @Bean(name = "secondDataSource") public DataSource dataSource(){ return DataSourceBuilder.create() .driverClassName(env.getProperty("datasource.two.driver")) .url(env.getProperty("datasource.two.url")) .username(env.getProperty("datasource.two.username")) .password(env.getProperty("datasource.two.password")) .build(); } @Bean(name = "secondSqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception{ SqlSessionFactoryBean bean=new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/second/*.xml")); return bean.getObject(); } @Bean(name = "secondTransactionManager") public DataSourceTransactionManager transactionManager(@Qualifier("secondDataSource") DataSource dataSource) throws Exception{ return new DataSourceTransactionManager(dataSource); } @Bean(name = "secondSqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory)throws Exception{ return new SqlSessionTemplate(sqlSessionFactory); }}


至此,我们该做的准备工作都做完了,下面我们进入测试环境。在controller包下建一个controller,并写一个请求方法,用于同时访问主数据源以及从数据源的数据,其源代码如下所示:

/** * 多数据源controller * @Author:debug (SteadyJack) * @Link: weixin-> debug0868 qq-> 1948831260 * @Date: 2019/11/7 10:37 **/@RestController@RequestMapping("multipart/source")public class MultipartSourceController { private static final Logger log= LoggerFactory.getLogger(MultipartSourceController.class); //TODO:从数据源的 @Autowired private SysConfigMapper sysConfigMapper; //TODO:主数据源的 @Autowired private UserMapper userMapper; @RequestMapping(value = "list",method = RequestMethod.GET) public BaseResponse list(){ BaseResponse response=new BaseResponse(StatusCode.Success); Map resMap= Maps.newHashMap(); try { resMap.put("主数据源",userMapper.selectByPrimaryKey(11)); resMap.put("从数据源",sysConfigMapper.selectActiveConfigs()); }catch (Exception e){ response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage()); } response.setData(resMap); return response; }}

之后,在Postman发起对应的请求,即可看到相应的响应结果!

8db34f05d0de489cafa4cf5de4db432e

看到结果,大家会发现没啥问题,确实实现了“主、从数据源”的多库访问,整个过程下来,大家会发现这只需要N个DataSource的显示注入即可实现(N=数据库的个数)!

而且,这种多数据源的实现方式还可以很好的支持“多数据源-跨库事务”,即在一个方法里面,如果需要同时执行“更新”N个数据库的操作,加了@Transactional(rollbackFor = Exception.class) 注解后,是可以实现“事务回滚的”,如下所示:

//TODO:多数据源时-跨事务 @RequestMapping(value = "add",method = RequestMethod.POST) @Transactional(rollbackFor = Exception.class) public BaseResponse add(@RequestParam String name) throws Exception{ BaseResponse response=new BaseResponse(StatusCode.Success); User user=new User(); user.setName(name); user.setCode("100"); userMapper.insertSelective(user); SysConfig config=new SysConfig(); config.setName(name); //有些字典必填,故而插入时会报错,测试是否会回滚 sysConfigMapper.insertSelective(config); return response; }

好了,本篇文章我们就介绍到这里了,其他相关的技术,感兴趣的小伙伴可以私信Debug了解课程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值