- 多数据源
- 动态数据源
多数据源
在pom中导入依赖
复制代码
1
2
3
4
5
6
7
8
9
10
11<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency>
多数据源在配置文件时要加入你所需要的多个数据源的信息
复制代码
1
2
3
4
5
6
7
8
9
10mybatis.config-location=classpath:mybatis/mybatis-config.xml spring.datasource.one.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.one.username=root spring.datasource.one.password=root spring.datasource.one.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.two.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.two.username=root spring.datasource.two.password=root spring.datasource.two.driver-class-name=com.mysql.cj.jdbc.Driver
为两个数据源创建不同的mapper包路径
例如:原来的单数据源将接口文档建在mapper包下,而多数据源建在mapper包下在分出来one包和two包,放置接口文件,对应的映射文件也是如此。
配置第⼀个数据源,新建 DataSource1Config。值得注意的是在配置数据源时要用@Primary指定主数据源
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30@Configuration @MapperScan(basePackages = "com.neo.mapper.one", sqlSessionTemplateRef = "oneSqlSessionTemplate") public class DataSource1Config { @Bean(name = "oneDataSource") @ConfigurationProperties(prefix = "spring.datasource.one") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "oneSqlSessionFactory") @Primary public SqlSessionFactory testSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/one/*.xml")); return bean.getObject(); } @Bean(name = "oneTransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "oneSqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
basePackages 指明 Mapper 地址。
sqlSessionTemplateRef 指定 Mapper 路径下注⼊的 sqlSessionTemplate。
第⼆个数据源配置
DataSource2Config 的配置和上⾯类似,⽅法上需要去掉 @Primary 注解,替换对应的数据源和 Mapper 路
径即可。下⾯是 DataSource2Config
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26@Configuration @MapperScan(basePackages = "com.neo.mapper.two", sqlSessionTemplateRef = "twoSqlSessionTemplate") public class DataSource2Config { @Bean(name = "twoDataSource") @ConfigurationProperties(prefix = "spring.datasource.two") public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "twoSqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/two/*.xml")); return bean.getObject(); } @Bean(name = "twoTransactionManager") public DataSourceTransactionManager testTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "twoSqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
接下来就是注入
复制代码
1
2
3
4
5@Autowired private User1Mapper user1Mapper; @Autowired private User2Mapper user2Mapper;
动态数据源
使用spring aop来动态切换数据源
Spring动态切换数据库的原理是通过继承AbstractRoutingDataSource重写determineCurrentLookupKey()方法,来决定使用那个数据库。在开启事务之前,通过改变lookupKey来达到切换数据源目的。
先写DataSourceContextHolder用来保存当前线程的数据库源。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class DataSourceContextHolder { /** * 默认数据源 */ public static final String DEFAULT_DS = "masterRds"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); // 设置数据源名 public static void setDB(String dbType) { contextHolder.set(dbType); } // 获取数据源名 public static String getDB() { return (contextHolder.get()); } // 清除数据源名 public static void clearDB() { contextHolder.remove(); } }
DynamicDataSource
复制代码
1
2
3
4
5
6
7
8@Component public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDB(); } }
配置数据源
DataSourceConfig
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84@Component @Configuration public class DataSourceConfig { @Value("${spring.datasource.master.url}") String masterUrl; @Value("${spring.datasource.master.username}") String masterUsername; @Value("${spring.datasource.master.password}") String masterPassword; @Value("${spring.datasource.master.driver-class-name}") String masterDriverClassName; @Bean(name = "masterRds") public DataSource masterDs() { DruidDataSource datasource1 = new DruidDataSource(); datasource1.setUrl(masterUrl); datasource1.setUsername(masterUsername); datasource1.setPassword(masterPassword); datasource1.setDriverClassName(masterDriverClassName); return datasource1; } @Value("${spring.datasource.cluster-rds.url}") String clusterUrl; @Value("${spring.datasource.cluster-rds.username}") String clusterUsername; @Value("${spring.datasource.cluster-rds.password}") String clusterPassword; @Value("${spring.datasource.cluster-rds.driver-class-name}") String clusterDriverClassName; @Bean(name = "clusterRds") public DataSource clusterRds() { DruidDataSource datasource1 = new DruidDataSource(); datasource1.setUrl(clusterUrl); datasource1.setUsername(clusterUsername); datasource1.setPassword(clusterPassword); datasource1.setDriverClassName(clusterDriverClassName); return datasource1; } @Value("${spring.datasource.user-datasouce.url}") String userUrl; @Value("${spring.datasource.user-datasouce.username}") String userUsername; @Value("${spring.datasource.user-datasouce.password}") String userPassword; @Value("${spring.datasource.user-datasouce.driver-class-name}") String userDriverClassName; @Bean(name = "userDs") public DataSource userDs() { DruidDataSource datasource1 = new DruidDataSource(); datasource1.setUrl(userUrl); datasource1.setUsername(userUsername); datasource1.setPassword(userPassword); datasource1.setDriverClassName(userDriverClassName); return datasource1; } /** * 动态数据源: 通过AOP在不同数据源之间动态切换 * * @return */ @Primary @Bean(name = "dynamicDataSource") public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); // 默认数据源 dynamicDataSource.setDefaultTargetDataSource(masterDs()); // 配置多数据源 Map<Object, Object> dsMap = Maps.newHashMap(); dsMap.put("masterRds", masterDs()); dsMap.put("clusterRds", clusterRds()); dsMap.put("userDs",userDs()); dynamicDataSource.setTargetDataSources(dsMap); return dynamicDataSource; } /** * 配置@Transactional注解事物 * * @return */ @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dynamicDataSource()); } }
使用aop来进行切换
定义注解
复制代码
1
2
3
4
5
6
7@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Documented public @interface DS { String value() default "masterRds"; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36@Aspect @Component public class DynamicDataSourceAspect { @Before("@annotation(ds)") public void beforeSwitchDS(JoinPoint point, DS ds) { //获得当前访问的class Class<?> className = point.getTarget().getClass(); //获得访问的方法名 String methodName = point.getSignature().getName(); //得到方法的参数的类型 Class[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes(); String dataSource = DataSourceContextHolder.DEFAULT_DS; try { // 得到访问的方法对象 Method method = className.getMethod(methodName, argClass); // 判断是否存在@DS注解 if (method.isAnnotationPresent(DS.class)) { DS annotation = method.getAnnotation(DS.class); // 取出注解中的数据源名 dataSource = annotation.value(); } } catch (Exception e) { e.printStackTrace(); } // 切换数据源 DataSourceContextHolder.setDB(dataSource); } @AfterReturning("@annotation(ds)") public void afterSwitchDS(JoinPoint point, DS ds) { String db = DataSourceContextHolder.getDB(); DataSourceContextHolder.clearDB(); DataSourceContextHolder.setDB(DataSourceContextHolder.DEFAULT_DS); String db1 = DataSourceContextHolder.getDB(); } }
使用
复制代码
1
2
3
4
5
6@DS("clusterRds") public int selectNum() { return authCenterMapper.selectNum(); }
最后
以上就是快乐万宝路最近收集整理的关于springboot使用mybatis多数据源和动态数据源的全部内容,更多相关springboot使用mybatis多数据源和动态数据源内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复