对于多数据源,一般都是问了解决主从模式或者业务相对复杂需要分库来支持业务的场景。搜索解决方案,要么是采用spring多数据源的方案,要么是利用aop动态切换,感觉有点小复杂,本文采用一种相对简单的解决方案,配置过程中遇到一些问题,特以此文记录
配置yml
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
| multi: datasource: enabled: true druid: master: url: jdbc:mysql://ip:port/master?useUnicode=true&characterEncoding=utf-8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false&useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver slave: url: jdbc:mysql://ip:port/slave?useUnicode=true&characterEncoding=utf-8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false&useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver mybatis: master: base-packages: com.fly.mapper.master mapper-locations: classpath:mapper/master/*.xml slave: base-packages: com.fly.mapper.slave mapper-locations: classpath:mapper/slave/*.xml
mybatis: type-aliases-package: com.fly.bean.mysql configuration: cache-enabled: true lazy-loading-enabled: true aggressive-lazy-loading: false multiple-result-sets-enabled: true use-column-label: true use-generated-keys: true auto-mapping-behavior: full default-executor-type: batch default-statement-timeout: 25000 mapUnderscoreToCamelCase: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
配置数据源
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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
@org.springframework.context.annotation.Configuration @ConditionalOnProperty(name = "multi.datasource.enabled", havingValue = "true") public class MultiDataSourceConfig {
@org.springframework.context.annotation.Configuration @ConditionalOnProperty(name = "multi.datasource.enabled", havingValue = "true") @MapperScan( basePackages = "com.fly.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory" ) @Getter @Setter @ConfigurationProperties( prefix = "multi.datasource.mybatis.master" ) static class MasterDataSourceConfig {
@javax.annotation.Resource MybatisConfigurationSupport support;
private String[] mapperLocations;
@ConfigurationProperties( prefix = "multi.datasource.druid.master" ) @Primary @Bean public DataSource masterDataSource() { return DruidDataSourceBuilder .create() .build(); }
@Bean @Primary public SqlSessionFactoryBean masterSqlSessionFactory( @Qualifier("masterDataSource") DataSource dataSource ) throws Exception { return support.createSqlSessionFactoryBean(dataSource, mapperLocations); }
}
@org.springframework.context.annotation.Configuration @ConditionalOnProperty(name = "multi.datasource.enabled", havingValue = "true") @MapperScan( basePackages = "com.fly.mapper.slave", sqlSessionFactoryRef = "slaveSqlSessionFactory" ) @Getter @Setter @ConfigurationProperties( prefix = "multi.datasource.mybatis.slave" ) static class SlaveDataSourceConfig { private String[] mapperLocations;
@javax.annotation.Resource MybatisConfigurationSupport support;
@ConfigurationProperties( prefix = "multi.datasource.druid.slave" ) @Bean public DataSource slaveDataSource() { return DruidDataSourceBuilder .create() .build(); }
@Bean public SqlSessionFactoryBean slaveSqlSessionFactory( @Qualifier("slaveDataSource") DataSource dataSource ) throws Exception { return support.createSqlSessionFactoryBean(dataSource, mapperLocations); } }
@Component @ConditionalOnProperty(name = "multi.datasource.enabled", havingValue = "true") static class MybatisConfigurationSupport { private final MybatisProperties properties; private final ResourceLoader resourceLoader;
public MybatisConfigurationSupport( MybatisProperties properties, ResourceLoader resourceLoader) { this.properties = properties; this.resourceLoader = resourceLoader; }
public SqlSessionFactoryBean createSqlSessionFactoryBean(DataSource dataSource, String[] mapperLocations) { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setVfs(SpringBootVFS.class);
Configuration configuration = new Configuration(); if (properties.getConfiguration() != null) { BeanUtils.copyProperties(properties.getConfiguration(), configuration); } factory.setConfiguration(configuration);
if (!ObjectUtils.isEmpty(mapperLocations)) { factory.setMapperLocations(resolveMapperLocations(mapperLocations)); }
return factory; }
public Resource[] resolveMapperLocations(String[] mapperLocations) { ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); List<Resource> resources = new ArrayList<>(); if (mapperLocations != null) { for (String mapperLocation : mapperLocations) { try { Resource[] mappers = resourceResolver.getResources(mapperLocation); resources.addAll(Arrays.asList(mappers)); } catch (IOException ignore) { ignore.printStackTrace(); } } } return resources.toArray(new Resource[resources.size()]); } } }
|
参考链接