首页
归档
留言
广告合作
友链
美女主播
Search
1
博瑞GE车机升级/降级
5,173 阅读
2
修改elementUI中el-table树形结构图标
4,540 阅读
3
Mac打印机设置黑白打印
4,535 阅读
4
Mac客户端添加腾讯企业邮箱方法
4,372 阅读
5
intelliJ Idea 2022.2.X破解
4,092 阅读
Java
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
登录
/
注册
Search
标签搜索
Spring Boot
Java
Spring Cloud
Mac
mybatis
WordPress
Nacos
Spring Cloud Alibaba
Mybatis-Plus
jQuery
Java Script
asp.net
微信小程序
Sentinel
UniApp
MySQL
asp.net core
IntelliJ IDEA
Jpa
树莓派
Laughing
累计撰写
576
篇文章
累计收到
1,425
条评论
首页
栏目
Java
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
页面
归档
留言
广告合作
友链
美女主播
搜索到
1
篇与
的结果
2021-04-24
Spring Boot 2.0+ ByBatis-Plus动态切换数据源
前端时间做了一个SaaS的应用,也是第一次弄SaaS相关软件。系统设计的不同租户之前是数据库级别的隔离。所以核心的内容基本就是如何实现不同之间的数据源的切换。创建模拟数据库创建两个数据库,分别命名为dynamic_datasource_one和dynamic_datasource_two,两个数据库内分别创建两张表,分别名称为table_one和table_two。数据库名表名dynamic_datasource_onetable_onedynamic_datasource_twotable_two创建表的Sql如下:create table table_one ( id bigint auto_increment primary key, name varchar(30) null ); INSERT INTO table_one (id, name) VALUES (1, 'dynamic_datasource_one'); create table table_two ( id bigint auto_increment primary key, name varchar(30) null ); INSERT INTO table_two (id, name) VALUES (1, 'dynamic_datasource_two');创建工程创建工程就不多说了,主要是添加mybatis-plus依赖就好了。 <!-- 添加MyBatis-plus依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.4.1</version> </dependency>修改配置文件配置两个数据库的连接信息,我这里放到配置文件中,如果是多租户的,也可以从数据库里面获取数据库连接信息。spring: datasource: url: jdbc:mysql://localhost:3306/dynamic_datasource_one?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: type-aliases-package: net.xiangcaowuyu.DynamicDataSource.doamin mapper-locations: classpath:mapper/*Mapper.xml添加配置文件将yaml中的配置信息映射到类上,方便使用。创建MyBatisConfig.java@Configuration @EnableTransactionManagement public class MyBatisConfig { private final Logger logger = LoggerFactory.getLogger(MyBatisConfig.class); /** * 数据源1 * @return */ public DataSource dynamicDataSourceOne( ) { return DataSourceBuilder .create() .url("jdbc:mysql://localhost:3306/dynamic_datasource_one?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true") .username("root") .password("123456") .driverClassName("com.mysql.jdbc.Driver") .build(); } /** * 数据源2 * @return */ public DataSource dynamicDataSourceTwo() { return DataSourceBuilder .create() .url("jdbc:mysql://localhost:3306/dynamic_datasource_two?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true") .username("root") .password("123456") .driverClassName("com.mysql.jdbc.Driver") .build(); } @Bean("dynamicDataSource") public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); DataSource dynamicDataSourceOne = dynamicDataSourceOne(); DataSource dynamicDataSourceTwo = dynamicDataSourceTwo(); Map<Object,Object> dynamicDataSourceMap = new HashMap<>(); dynamicDataSourceMap.put("dynamicDataSourceOne",dynamicDataSourceOne); dynamicDataSourceMap.put("dynamicDataSourceTwo",dynamicDataSourceTwo); DynamicDataSourceContextHolder.addDataSourceKeys(dynamicDataSourceMap.keySet()); dynamicDataSource.setTargetDataSources(dynamicDataSourceMap); //必须执行此操作,才会重新初始化AbstractRoutingDataSource 中的 resolvedDataSources,也只有这样,动态切换才会起效 dynamicDataSource.afterPropertiesSet(); return dynamicDataSource; } }创建DataSourceContextHolder存储当前数据源public class DynamicDataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(){ @Override protected String initialValue(){ return "dynamicDataSourceOne"; } }; public static List<Object> dataSourceKeyList = new ArrayList<>(); public static void setDataSourceKey(String key) throws Exception { if(!dataSourceKeyList.contains(key)){ throw new Exception("数据库连接不存在"); } contextHolder.set(key); } public static String getDataSourceKey(){ return contextHolder.get(); } public static void clearDataSourceKey(String key){ contextHolder.remove(); } /** * 添加数据库连接键 * @param keys */ public static void addDataSourceKeys(Collection<Object> keys){ dataSourceKeyList.addAll(keys); } }创建DynamicDataSource配置每次执行sql时,调用的数据源。/** * 动态数据源 */ public class DynamicDataSource extends AbstractRoutingDataSource { /** * 设置数据源Key值来切换数据,每次执行sql会先调用这个方法 * @return */ @Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getDataSourceKey(); } }测试创建MapperTableOneMapper@Mapper public interface TableOneMapper extends BaseMapper<TableOne> { }TableTwoMapper@Mapper public interface TableTwoMapper extends BaseMapper<TableOne> { }创建controller@RestController @RequestMapping("/") public class DynamicDatSourceController { private final Logger logger = LoggerFactory.getLogger(DynamicDatSourceController.class); @Resource TableOneMapper tableOneMapper; @Resource TableTwoMapper tableTwoMapper; @GetMapping public void test() throws Exception { logger.info("准备查询数据源1的数据"); logger.info(tableOneMapper.selectList(new QueryWrapper<>()).get(0).getName()); logger.info("准备查询数据源2的数据"); DynamicDataSourceContextHolder.setDataSourceKey("dynamicDataSourceTwo"); logger.info(tableTwoMapper.selectList(new QueryWrapper<>()).get(0).getName()); } }
2021年04月24日
1,213 阅读
0 评论
0 点赞