SpringBoot、MyBatis配置多数据源XML方法
2016-12-17 16:42
761 查看
转载请注明来源-作者@loongshawn:http://blog.csdn.net/loongshawn/article/details/52164730
开发中有时候会碰到使用多个数据源的情况,这种情况也分两种不同的业务场景:
(1)、多个数据源是各自独立的,可以把它当作不同的项目来开发。比如一个是业务1的数据库,另一个是业务2的数据库。
(2)、多个数据源之间是主从关系(master-slave),其中一个数据库是master库,另外几个是slave库,从库需要同步主库的更新及变化。
当前我的业务是在同一个工程中,接入另外一个数据库,提供计算与API服务,与当前工程所使用的库没有关联,两个数据库独立,所以我只需要针对上述场景(1)调整配置即可。
修改application-dev.properties文件,新增数据库配置地址及权限。
单一库时的配置:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
新增一个库后的配置:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
说明:第二个数据源中只需要修改数据库地址及权限即可,数据库的基本配置参数可与数据源一公用。
原来单一数据源时的文件内容:
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
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
新增数据源后的文件内容:
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
其中新增的配置如下,同时大家需要注意以下几点:
dataSource2、sqlSessionFactory2、mybatisMapperScanner2的名字改写,与数据源一不要一样。
在mybatisMapperScanner、mybatisMapperScanner2中添加属性sqlSessionFactoryBeanName,值为sqlSessionFactory、sqlSessionFactory2。
下面为新增的数据源配置:
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
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
如上所示,我们分别配置了两个 dataSource,两个sqlSessionFactory,两个mybatisMapperScanner,以及关键的地方在于MapperScannerConfigurer 的配置——使用sqlSessionFactoryBeanName属性,注入不同的sqlSessionFactory的名称,这样的话,就为不同的数据库对应的 mapper 接口注入了对应的 sqlSessionFactory。
工程运行后,可同时连接2个数据库进行相关业务操作。
新建测试类QuarterTest,其中quarterMapper来自数据源一,projectMapper来自数据源二:
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
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
(1)工程运行正常
(2)任务执行结果
第一个数据源查询结果为45条记录:
第二个数据源查询结果为29条记录:
Console输出结果:
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
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
上面的这种多数据源配置是不支持分布式事务的,也就是同一个事务中,不能操作多个数据库。这种配置方式的优点是很简单,但是却不灵活,需要依据业务场景来选择,如我当前的业务场景通过上述配置即可快速达成要求。
对于master-slave类型的多数据源配置而言不太适应,master-slave性的多数据源的配置,需要特别灵活,需要根据业务的类型进行细致的配置。比如对于一些耗时特别大的select语句,我们希望放到slave上执行,而对于update,delete等操作肯定是只能在master上执行的,另外对于一些实时性要求很高的select语句,我们也可能需要放到master上执行——比如一个场景是打游戏过程中,去商城购买一件兵器,购买操作的很定是master,同时购买完成之后,需要重新查询出我所拥有的兵器和金币,那么这个查询可能也需要防止master上执行,而不能放在slave上去执行,因为slave上可能存在延时,我们可不希望玩家发现购买成功之后,在背包中却找不到兵器的情况出现。
至于如何解决这种场景下的多数据库源配置,还有待继续学习。在此我整理了部分网络上的解决方案:
对于master-slave类型的多数据源的配置,需要根据业务来进行灵活的配置,哪些select可以放到slave上,哪些select不能放到slave上。所以上面的那种所数据源的配置就不太适应了,需要采用另外一套方式。即,利用基于 AbstractRoutingDataSource 和 AOP 的多数据源的配置。
其基本原理是,自己定义一个DataSource类ThreadLocalRountingDataSource,来继承AbstractRoutingDataSource,然后在配置文件中向ThreadLocalRountingDataSource注入 master 和 slave 的数据源,然后通过 AOP 来灵活配置,在哪些地方选择 master 数据源,在哪些地方需要选择 slave数据源。具体实现将会在后续文章中说明。
1、介绍
开发中有时候会碰到使用多个数据源的情况,这种情况也分两种不同的业务场景:(1)、多个数据源是各自独立的,可以把它当作不同的项目来开发。比如一个是业务1的数据库,另一个是业务2的数据库。
(2)、多个数据源之间是主从关系(master-slave),其中一个数据库是master库,另外几个是slave库,从库需要同步主库的更新及变化。
2、背景
当前我的业务是在同一个工程中,接入另外一个数据库,提供计算与API服务,与当前工程所使用的库没有关联,两个数据库独立,所以我只需要针对上述场景(1)调整配置即可。
3、配置
3.1、修改application-dev.properties文件
修改application-dev.properties文件,新增数据库配置地址及权限。单一库时的配置:
# mysql第一数据源 spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_2 spring.datasource.username=test spring.datasource.password=test spring.datasource.initialSize=10 spring.datasource.maxActive=99 spring.datasource.maxIdle=20 spring.datasource.minIdle=9 spring.datasource.removeAbandoned=true spring.datasource.removeAbandonedTimeout=180 spring.datasource.maxWait=60000 spring.datasource.validationQuery=select 1 from dual spring.datasource.testOnBorrow=true spring.datasource.connectionProperties=clientEncoding=UTF-81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
新增一个库后的配置:
# mysql第一数据源 spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_1 spring.datasource.username=test spring.datasource.password=test spring.datasource.initialSize=10 spring.datasource.maxActive=99 spring.datasource.maxIdle=20 spring.datasource.minIdle=9 spring.datasource.removeAbandoned=true spring.datasource.removeAbandonedTimeout=180 spring.datasource.maxWait=60000 spring.datasource.validationQuery=select 1 from dual spring.datasource.testOnBorrow=true spring.datasource.connectionProperties=clientEncoding=UTF-8 # mysql第二数据源 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_2 spring.datasource.username=test spring.datasource.password=test1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
说明:第二个数据源中只需要修改数据库地址及权限即可,数据库的基本配置参数可与数据源一公用。
3.2、修改applicationContext.xml文件
原来单一数据源时的文件内容:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:spring/config/application-dev.properties</value> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true" /> </bean> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${spring.datasource.driverClassName}" /> <property name="url" value="${spring.datasource.url}" /> <property name="username" value="${spring.datasource.username}" /> <property name="password" value="${spring.datasource.password}" /> <property name="initialSize" value="${spring.datasource.initialSize}" /> <property name="maxActive" value="${spring.datasource.maxActive}" /> <property name="maxIdle" value="${spring.datasource.maxIdle}" /> <property name="minIdle" value="${spring.datasource.minIdle}" /> <property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" /> <property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" /> <property name="maxWait" value="${spring.datasource.maxWait}" /> <property name="validationQuery" value="${spring.datasource.validationQuery}" /> <property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" /> <property name="connectionProperties" value="${spring.datasource.connectionProperties}" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper/*.xml" /> <property name="typeAliasesPackage" value="com.autonavi.domain" /> </bean> <!-- mybatis.spring自动映射 --> <bean id="mybatisMapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.autonavi.dao.impl.mapper" /> <!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />--> </bean> <bean id="springContextUtil" class="com.autonavi.utils.MyApplicationContextUtil"/> <bean id="appErrorController" class="com.autonavi.controller.AppErrorController"/> <!-- Enables the Spring Task @Scheduled programming model --> <task:executor id="executor" pool-size="10" /> <task:scheduler id="scheduler" pool-size="20" /> <task:annotation-driven executor="executor" scheduler="scheduler" /> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthenticatedException">pages/403</prop> <prop key="org.apache.shiro.authz.UnauthorizedException">pages/403</prop> <prop key="org.apache.shiro.authc.LockedAccountException">pages/locked</prop> <prop key="java.lang.Throwable">pages/500</prop> </props> </property> </bean> </beans>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
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
新增数据源后的文件内容:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:spring/config/application-dev.properties</value> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true" /> </bean> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${spring.datasource.driverClassName}" /> <property name="url" value="${spring.datasource.url}" /> <property name="username" value="${spring.datasource.username}" /> <property name="password" value="${spring.datasource.password}" /> <property name="initialSize" value="${spring.datasource.initialSize}" /> <property name="maxActive" value="${spring.datasource.maxActive}" /> <property name="maxIdle" value="${spring.datasource.maxIdle}" /> <property name="minIdle" value="${spring.datasource.minIdle}" /> <property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" /> <property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" /> <property name="maxWait" value="${spring.datasource.maxWait}" /> <property name="validationQuery" value="${spring.datasource.validationQuery}" /> <property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" /> <property name="connectionProperties" value="${spring.datasource.connectionProperties}" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper/*.xml" /> <property name="typeAliasesPackage" value="com.autonavi.domain" /> </bean> <!-- mybatis.spring自动映射 --> <bean id="mybatisMapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.autonavi.dao.impl.mapper" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <!-- 第二个数据源配置 --> <bean id="dataSource2" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${spring.datasource.driverClassName}" /> <property name="url" value="${spring.datasource.url2}" /> <property name="username" value="${spring.datasource.username2}" /> <property name="password" value="${spring.datasource.password2}" /> <property name="initialSize" value="${spring.datasource.initialSize}" /> <property name="maxActive" value="${spring.datasource.maxActive}" /> <property name="maxIdle" value="${spring.datasource.maxIdle}" /> <property name="minIdle" value="${spring.datasource.minIdle}" /> <property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" /> <property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" /> <property name="maxWait" value="${spring.datasource.maxWait}" /> <property name="validationQuery" value="${spring.datasource.validationQuery}" /> <property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" /> <property name="connectionProperties" value="${spring.datasource.connectionProperties}" /> </bean> <bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource2" /> <property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper2/*.xml" /> <property name="typeAliasesPackage" value="com.autonavi.domain" /> </bean> <!-- mybatis.spring自动映射 --> <bean id="mybatisMapperScanner2" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.autonavi.dao.impl.mapper2.pmp" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2" /> </bean> <bean id="springContextUtil" class="com.autonavi.utils.MyApplicationContextUtil"/> <bean id="appErrorController" class="com.autonavi.controller.AppErrorController"/> <!-- Enables the Spring Task @Scheduled programming model --> <task:executor id="executor" pool-size="10" /> <task:scheduler id="scheduler" pool-size="20" /> <task:annotation-driven executor="executor" scheduler="scheduler" /> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthenticatedException">pages/403</prop> <prop key="org.apache.shiro.authz.UnauthorizedException">pages/403</prop> <prop key="org.apache.shiro.authc.LockedAccountException">pages/locked</prop> <prop key="java.lang.Throwable">pages/500</prop> </props> </property> </bean> </beans>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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
其中新增的配置如下,同时大家需要注意以下几点:
dataSource2、sqlSessionFactory2、mybatisMapperScanner2的名字改写,与数据源一不要一样。
在mybatisMapperScanner、mybatisMapperScanner2中添加属性sqlSessionFactoryBeanName,值为sqlSessionFactory、sqlSessionFactory2。
下面为新增的数据源配置:
<!-- 第二个数据源配置 --> <bean id="dataSource2" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${spring.datasource.driverClassName}" /> <property name="url" value="${spring.datasource.url2}" /> <property name="username" value="${spring.datasource.username2}" /> <property name="password" value="${spring.datasource.password2}" /> <property name="initialSize" value="${spring.datasource.initialSize}" /> <property name="maxActive" value="${spring.datasource.maxActive}" /> <property name="maxIdle" value="${spring.datasource.maxIdle}" /> <property name="minIdle" value="${spring.datasource.minIdle}" /> <property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" /> <property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" /> <property name="maxWait" value="${spring.datasource.maxWait}" /> <property name="validationQuery" value="${spring.datasource.validationQuery}" /> <property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" /> <property name="connectionProperties" value="${spring.datasource.connectionProperties}" /> </bean> <bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource2" /> <property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper2/*.xml" /> <property name="typeAliasesPackage" value="com.autonavi.domain" /> </bean> <!-- mybatis.spring自动映射 --> <bean id="mybatisMapperScanner2" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.autonavi.dao.impl.mapper2.pmp" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2" /> </bean>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
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
如上所示,我们分别配置了两个 dataSource,两个sqlSessionFactory,两个mybatisMapperScanner,以及关键的地方在于MapperScannerConfigurer 的配置——使用sqlSessionFactoryBeanName属性,注入不同的sqlSessionFactory的名称,这样的话,就为不同的数据库对应的 mapper 接口注入了对应的 sqlSessionFactory。
4、测试
4.1、测试要求
工程运行后,可同时连接2个数据库进行相关业务操作。
4.2、新建测试用例
新建测试类QuarterTest,其中quarterMapper来自数据源一,projectMapper来自数据源二:public class QuarterTest { private static final Logger logger = LoggerFactory.getLogger(QuarterTest.class); @Autowired private QuarterMapper quarterMapper; public void action(){ // no.1 初始化工作 quarterMapper = MyApplicationContextUtil.getBean("quarterMapper"); ProjectMapper projectMapper = MyApplicationContextUtil.getBean("projectMapper"); List<Version> list1 = quarterMapper.selectQuarters(); List<Version> list2 = projectMapper.selectQuarters(); logger.info("数据源1,size:{}",list1.size()); for(Version quarter : list1){ logger.info("QuarterTest.method [action]: info id:{},version_name:{},year:{},fiscal_year:{}", quarter.getId(),quarter.getVersion_name(),quarter.getYear(),quarter.getFiscal_year()); } logger.info("数据源2,size:{}",list2.size()); for(Version quarter : list2){ logger.info("QuarterTest.method [action]: info id:{},version_name:{},year:{},fiscal_year:{}", quarter.getId(),quarter.getVersion_name(),quarter.getYear(),quarter.getFiscal_year()); } } }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
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
4.3、测试结果
(1)工程运行正常(2)任务执行结果
第一个数据源查询结果为45条记录:
第二个数据源查询结果为29条记录:
Console输出结果:
2016-08-09-14-22 [scheduler-3] [com.autonavi.task.ScheduledTasks] [INFO] - ScheduledTest.executeFileDownLoadTask 定时任务1:17,name:scheduler-3 2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ooo Using Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@56b5dd08]]] 2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ==> Preparing: SELECT id, version_name, year, fiscal_year FROM version_table 2016-08-09-14-22 [scheduler-2] [java.sql.PreparedStatement] [DEBUG] - ==> Parameters: 2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ooo Using Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@65e921a2]]] 2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ==> Preparing: SELECT id, version_name, year, fiscal_year FROM version_table 2016-08-09-14-22 [scheduler-2] [java.sql.PreparedStatement] [DEBUG] - ==> Parameters: 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - 数据源1,size:45 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:1,version_name:2016Q1,year:2016,fiscal_year:2015 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:2,version_name:2016Q2,year:2016,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:3,version_name:2016Q3,year:2016,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:4,version_name:2016Q4,year:2016,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:5,version_name:2017Q1,year:2017,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:6,version_name:2017Q2,year:2017,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:7,version_name:2017Q3,year:2017,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:8,version_name:2017Q4,year:2017,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:9,version_name:2018Q1,year:2018,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:10,version_name:2018Q2,year:2018,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:11,version_name:2018Q3,year:2018,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:12,version_name:2018Q4,year:2018,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:13,version_name:2019Q1,year:2019,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:14,version_name:2019Q2,year:2019,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:15,version_name:2019Q3,year:2019,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:16,version_name:2019Q4,year:2019,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:17,version_name:2020Q1,year:2020,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:18,version_name:2020Q2,year:2020,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:19,version_name:2020Q3,year:2020,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:20,version_name:2020Q4,year:2020,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:21,version_name:2021Q1,year:2021,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:22,version_name:2021Q2,year:2021,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:23,version_name:2021Q3,year:2021,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:24,version_name:2021Q4,year:2021,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:25,version_name:2022Q1,year:2022,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:26,version_name:2022Q2,year:2022,fiscal_year:2022 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:27,version_name:2022Q3,year:2022,fiscal_year:2022 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:28,version_name:2022Q4,year:2022,fiscal_year:2022 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:29,version_name:2023Q1,year:2023,fiscal_year:2022 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:30,version_name:2023Q2,year:2023,fiscal_year:2023 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:31,version_name:2023Q3,year:2023,fiscal_year:2023 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:32,version_name:2023Q4,year:2023,fiscal_year:2023 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:33,version_name:2024Q1,year:2024,fiscal_year:2023 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:34,version_name:2024Q2,year:2024,fiscal_year:2024 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:35,version_name:2024Q3,year:2024,fiscal_year:2024 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:36,version_name:2024Q4,year:2024,fiscal_year:2024 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:37,version_name:2025Q1,year:2025,fiscal_year:2024 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:38,version_name:2025Q2,year:2025,fiscal_year:2025 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:39,version_name:2025Q3,year:2025,fiscal_year:2025 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:40,version_name:2025Q4,year:2025,fiscal_year:2025 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:41,version_name:2026Q1,year:2026,fiscal_year:2025 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:42,version_name:2026Q2,year:2026,fiscal_year:2026 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:43,version_name:2026Q3,year:2026,fiscal_year:2026 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:44,version_name:2026Q4,year:2026,fiscal_year:2026 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:45,version_name:2027Q1,year:2027,fiscal_year:2026 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - 数据源2,size:29 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:1,version_name:2016Q1,year:2016,fiscal_year:2015 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:2,version_name:2016Q2,year:2016,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:3,version_name:2016Q3,year:2016,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:4,version_name:2016Q4,year:2016,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:5,version_name:2017Q1,year:2017,fiscal_year:2016 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:6,version_name:2017Q2,year:2017,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:7,version_name:2017Q3,year:2017,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:8,version_name:2017Q4,year:2017,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:9,version_name:2018Q1,year:2018,fiscal_year:2017 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:10,version_name:2018Q2,year:2018,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:11,version_name:2018Q3,year:2018,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:12,version_name:2018Q4,year:2018,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:13,version_name:2019Q1,year:2019,fiscal_year:2018 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:14,version_name:2019Q2,year:2019,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:15,version_name:2019Q3,year:2019,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:16,version_name:2019Q4,year:2019,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:17,version_name:2020Q1,year:2020,fiscal_year:2019 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:18,version_name:2020Q2,year:2020,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:19,version_name:2020Q3,year:2020,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:20,version_name:2020Q4,year:2020,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:21,version_name:2021Q1,year:2021,fiscal_year:2020 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:22,version_name:2021Q2,year:2021,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:23,version_name:2021Q3,year:2021,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:24,version_name:2021Q4,year:2021,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:25,version_name:2022Q1,year:2022,fiscal_year:2021 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:26,version_name:2022Q2,year:2022,fiscal_year:2022 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:27,version_name:2022Q3,year:2022,fiscal_year:2022 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:28,version_name:2022Q4,year:2022,fiscal_year:2022 2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:29,version_name:2023Q1,year:2023,fiscal_year:20221
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
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
5、总结
上面的这种多数据源配置是不支持分布式事务的,也就是同一个事务中,不能操作多个数据库。这种配置方式的优点是很简单,但是却不灵活,需要依据业务场景来选择,如我当前的业务场景通过上述配置即可快速达成要求。对于master-slave类型的多数据源配置而言不太适应,master-slave性的多数据源的配置,需要特别灵活,需要根据业务的类型进行细致的配置。比如对于一些耗时特别大的select语句,我们希望放到slave上执行,而对于update,delete等操作肯定是只能在master上执行的,另外对于一些实时性要求很高的select语句,我们也可能需要放到master上执行——比如一个场景是打游戏过程中,去商城购买一件兵器,购买操作的很定是master,同时购买完成之后,需要重新查询出我所拥有的兵器和金币,那么这个查询可能也需要防止master上执行,而不能放在slave上去执行,因为slave上可能存在延时,我们可不希望玩家发现购买成功之后,在背包中却找不到兵器的情况出现。
至于如何解决这种场景下的多数据库源配置,还有待继续学习。在此我整理了部分网络上的解决方案:
对于master-slave类型的多数据源的配置,需要根据业务来进行灵活的配置,哪些select可以放到slave上,哪些select不能放到slave上。所以上面的那种所数据源的配置就不太适应了,需要采用另外一套方式。即,利用基于 AbstractRoutingDataSource 和 AOP 的多数据源的配置。
其基本原理是,自己定义一个DataSource类ThreadLocalRountingDataSource,来继承AbstractRoutingDataSource,然后在配置文件中向ThreadLocalRountingDataSource注入 master 和 slave 的数据源,然后通过 AOP 来灵活配置,在哪些地方选择 master 数据源,在哪些地方需要选择 slave数据源。具体实现将会在后续文章中说明。
相关文章推荐
- Spring Boot + Mybatis多数据源和动态数据源配置方法
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法(转)
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- Spring-boot Mybatis多数据源事务配置
- Spring-boot配置Mybatis多数据源
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- spring boot 配置MyBatis,支持多个数据源和分页插件
- springboot + mybatis配置多数据源示例
- spring-boot配置MySQL数据库连接、Hikari连接池、和Mybatis的简单方法
- springboot + mybatis配置多数据源示例
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- Spring Boot多数据源及其事务管理配置方法
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法
- springboot下配置多数据源的方法
- SpringBoot多数据源的配置(SpringBoot+MyBatis)
- spring mybatis 框架集成之applicationContext.xml配置方法