1,负载均衡和主从同步配置
可以通过mysql的协议配置支持,不在本文探讨范围。配置方式如下
jdbcUrl: jdbc:mysql:replication://host1:port1,host2:port2/dbname?useSSL=true&useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=true&serverTimezone=GMT%2B8
2,分库分表等类的多数据源配置,不在本文探讨范围。
略
3,其他使用多个不同业务数据源配置步骤如下:
数据库连接池以c3p0为例,并且启用了手动式事务管理。
3.1,配置数据库连接池类型
spring:
datasource:
# 使用c3p0数据库连接池
type: com.mchange.v2.c3p0.ComboPooledDataSource
3.2,不使用系统默认数据库配置,手动配置两个数据源
# 数据源配置
datasource:
master:
driverClass: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql:replication://localhost:3306/goods?useSSL=true&useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=true&serverTimezone=GMT%2B8
user: demotest
password: demotest
minPoolSize: 4
maxPoolSize: 20
maxIdleTime: 1800000
acquireIncrement: 2
maxStatements: 0
initialPoolSize: 4
idleConnectionTestPeriod: 60
acquireRetryAttempts: 5
acquireRetryDelay: 1000
breakAfterAcquireFailure: false
testConnectionOnCheckin: true
testConnectionOnCheckout: false
preferredTestQuery: SELECT 1 FROM DUAL
second:
driverClass: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql:replication://localhost:3306/users?useSSL=true&useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
user: usertest
password: usertest
minPoolSize: 4
maxPoolSize: 20
maxIdleTime: 1800000
acquireIncrement: 2
maxStatements: 0
initialPoolSize: 4
idleConnectionTestPeriod: 60
acquireRetryAttempts: 5
acquireRetryDelay: 1000
breakAfterAcquireFailure: false
testConnectionOnCheckin: true
testConnectionOnCheckout: false
preferredTestQuery: SELECT 1 FROM DUAL
3.3,配置两套MyBatis属性
# mybatis配置
mybatis:
master:
config-location: classpath:bean/mybatis/master/mybatis_config.xml
mapper-locations: classpath:/bean/mybatis/master/mapping/*.xml
type-aliases-package: com.beyonds.phoenix.demo.domain.dao.master.po
type-dao-package: com.beyonds.phoenix.demo.domain.dao.master
executorType: REUSE
second:
config-location: classpath:bean/mybatis/second/mybatis_config.xml
mapper-locations: classpath:/bean/mybatis/second/mapping/*.xml
type-aliases-package: com.beyonds.phoenix.demo.domain.dao.second.po
type-dao-package: com.beyonds.phoenix.demo.domain.dao.second
executorType: REUSE
3.4,配置第一个数据源config文件
@Configuration
@MapperScan(basePackages = {"${mybatis.type-dao-package:com.beyonds.phoenix.demo.domain.dao.master}"},
sqlSessionFactoryRef = "sqlSessionFactory")
@EnableTransactionManagement
@ConditionalOnMissingBean({DataSourceConfiguration.class})
@AutoConfigureOrder(-100)
@AutoConfigureAfter({MybatisAutoConfiguration.class})
public class DatasourceConfig {
protected static Logger logger = LoggerFactory.getLogger("DAO.LOG");
@Value("${spring.datasource.type}")
private Class<? extends DataSource> datasourceType;
/**
* 定义服务模板
* @param transactionTemplate 事务模板
* @return 服务模板
*/
@Bean(name = "wdServiceTemplate")
public WdServiceTemplateImpl wdServiceTemplate(
@Qualifier("transactionTemplate") TransactionTemplate transactionTemplate) {
return new WdServiceTemplateImpl(transactionTemplate);
}
/**
* 定义主数据源
* @return 主数据源
*/
@Bean(name = "dataSource", destroyMethod = "close")
@Primary
@ConfigurationProperties(prefix = "datasource.master")
public DataSource dataSource() {
return DataSourceBuilder.create().type(datasourceType).build();
}
/**
* 定义事务管理器
* @param dataSource 数据源
* @return 事务管理器
*/
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 定义事务模板
* @param transactionManager 事务管理器
* @return 事务模板
* @throws Exception 异常
*/
@Bean(name = "transactionTemplate")
public TransactionTemplate transactionTemplate(
@Qualifier("transactionManager") DataSourceTransactionManager transactionManager)
throws Exception {
DefaultTransactionDefinition defaultTransactionDefinition =
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED);
defaultTransactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
defaultTransactionDefinition.setTimeout(60); // 秒钟
return new TransactionTemplate(transactionManager, defaultTransactionDefinition);
}
/**
* +自定义数据源配置
* @param dataSource dataSource
* @param properties properties
* @param resourceLoader resourceLoader
* @param interceptorsProvider interceptorsProvider
* @param databaseIdProviderContainer databaseIdProviderContainer
* @param configurationCustomizersProvider configurationCustomizersProvider
* @return configurationCustomizersProvider
* @throws Exception Exception
*/
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("dataSource") DataSource dataSource,
@Qualifier("mybatisPropertiesMaster") MybatisProperties properties,
ResourceLoader resourceLoader,
ObjectProvider<Interceptor[]> interceptorsProvider,
ObjectProvider<DatabaseIdProvider> databaseIdProviderContainer,
ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider
) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(properties.getConfigLocation())) {
factory.setConfigLocation(resourceLoader.getResource(properties.getConfigLocation()));
}
org.apache.ibatis.session.Configuration configuration = properties.getConfiguration();
if (configuration == null && !StringUtils.hasText(properties.getConfigLocation())) {
configuration = new org.apache.ibatis.session.Configuration();
}
List<ConfigurationCustomizer> configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
if (configuration != null && !CollectionUtils.isEmpty(configurationCustomizers)) {
for (ConfigurationCustomizer customizer : configurationCustomizers) {
customizer.customize(configuration);
}
}
factory.setConfiguration(configuration);
if (properties.getConfigurationProperties() != null) {
factory.setConfigurationProperties(properties.getConfigurationProperties());
}
Interceptor[] interceptors = interceptorsProvider.getIfAvailable();
if (!ObjectUtils.isEmpty(interceptors)) {
factory.setPlugins(interceptors);
}
DatabaseIdProvider databaseIdProvider = databaseIdProviderContainer.getIfAvailable();
if (databaseIdProvider != null) {
factory.setDatabaseIdProvider(databaseIdProvider);
}
if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(properties.getTypeAliasesPackage());
}
if (StringUtils.hasLength(properties.getTypeHandlersPackage())) {
factory.setTypeHandlersPackage(properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(properties.resolveMapperLocations())) {
factory.setMapperLocations(properties.resolveMapperLocations());
}
return factory.getObject();
}
/**
* +定义配置文件
* @return MybatisProperties
*/
@Bean(name = "mybatisPropertiesMaster")
@ConfigurationProperties(prefix = "mybatis.master")
public MybatisProperties mybatisProperties() {
return new MybatisProperties();
}
}
3.5,配置第二个数据源config文件
@Configuration
@MapperScan(basePackages = {"${mybatis.type-dao-package:com.beyonds.phoenix.demo.domain.dao.second}"},
sqlSessionFactoryRef = "sqlSessionFactorySecond")
@EnableTransactionManagement
@ConditionalOnMissingBean({DataSourceConfiguration.class})
@AutoConfigureOrder(-90)
@AutoConfigureAfter({MybatisAutoConfiguration.class})
public class DatasourceSecondConfig {
protected static Logger logger = LoggerFactory.getLogger("DAO.LOG");
@Value("${spring.datasource.type}")
private Class<? extends DataSource> datasourceType;
/**
* 定义服务模板
* @param transactionTemplate 事务模板
* @return 服务模板
*/
@Bean(name = "wdServiceTemplateSecond")
public WdServiceTemplateImpl wdServiceTemplateSecond(
@Qualifier("transactionTemplateSecond") TransactionTemplate transactionTemplate) {
return new WdServiceTemplateImpl(transactionTemplate);
}
/**
* 定义主数据源
* @return 主数据源
*/
@Bean(name = "dataSourceSecond", destroyMethod = "close")
@ConfigurationProperties(prefix = "datasource.second")
public DataSource dataSourceSecond() {
return DataSourceBuilder.create().type(datasourceType).build();
}
/**
* 定义事务管理器
* @param dataSource 数据源
* @return 事务管理器
*/
@Bean(name = "transactionManagerSecond")
public DataSourceTransactionManager transactionManager(@Qualifier("dataSourceSecond") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 定义事务模板
* @param transactionManager 事务管理器
* @return 事务模板
* @throws Exception 异常
*/
@Bean(name = "transactionTemplateSecond")
public TransactionTemplate transactionTemplate(
@Qualifier("transactionManagerSecond") DataSourceTransactionManager transactionManager)
throws Exception {
DefaultTransactionDefinition defaultTransactionDefinition =
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED);
defaultTransactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
defaultTransactionDefinition.setTimeout(60); // 秒钟
return new TransactionTemplate(transactionManager, defaultTransactionDefinition);
}
/**
* +自定义数据源配置
* @param dataSource dataSource
* @param properties properties
* @param resourceLoader resourceLoader
* @param interceptorsProvider interceptorsProvider
* @param databaseIdProviderContainer databaseIdProviderContainer
* @param configurationCustomizersProvider configurationCustomizersProvider
* @return configurationCustomizersProvider
* @throws Exception Exception
*/
@Bean(name = "sqlSessionFactorySecond")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("dataSourceSecond") DataSource dataSource,
@Qualifier("mybatisPropertiesSecond") MybatisProperties properties,
ResourceLoader resourceLoader,
ObjectProvider<Interceptor[]> interceptorsProvider,
ObjectProvider<DatabaseIdProvider> databaseIdProviderContainer,
ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider
) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(properties.getConfigLocation())) {
factory.setConfigLocation(resourceLoader.getResource(properties.getConfigLocation()));
}
org.apache.ibatis.session.Configuration configuration = properties.getConfiguration();
if (configuration == null && !StringUtils.hasText(properties.getConfigLocation())) {
configuration = new org.apache.ibatis.session.Configuration();
}
List<ConfigurationCustomizer> configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
if (configuration != null && !CollectionUtils.isEmpty(configurationCustomizers)) {
for (ConfigurationCustomizer customizer : configurationCustomizers) {
customizer.customize(configuration);
}
}
factory.setConfiguration(configuration);
if (properties.getConfigurationProperties() != null) {
factory.setConfigurationProperties(properties.getConfigurationProperties());
}
Interceptor[] interceptors = interceptorsProvider.getIfAvailable();
if (!ObjectUtils.isEmpty(interceptors)) {
factory.setPlugins(interceptors);
}
DatabaseIdProvider databaseIdProvider = databaseIdProviderContainer.getIfAvailable();
if (databaseIdProvider != null) {
factory.setDatabaseIdProvider(databaseIdProvider);
}
if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(properties.getTypeAliasesPackage());
}
if (StringUtils.hasLength(properties.getTypeHandlersPackage())) {
factory.setTypeHandlersPackage(properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(properties.resolveMapperLocations())) {
factory.setMapperLocations(properties.resolveMapperLocations());
}
return factory.getObject();
}
/**
* +定义配置文件
* @return MybatisProperties
*/
@Primary
@Bean(name = "mybatisPropertiesSecond")
@ConfigurationProperties(prefix = "mybatis.second")
public MybatisProperties mybatisPropertiesSecond() {
return new MybatisProperties();
}
}
3.6,以上两步定义了两个不同的处理事务模板
@Bean(name = "wdServiceTemplate")
public WdServiceTemplateImpl wdServiceTemplate(
@Qualifier("transactionTemplate") TransactionTemplate transactionTemplate) {
return new WdServiceTemplateImpl(transactionTemplate);
}
和
@Bean(name = "wdServiceTemplateSecond")
public WdServiceTemplateImpl wdServiceTemplate(
@Qualifier("transactionTemplateSecond") TransactionTemplate transactionTemplate) {
return new WdServiceTemplateImpl(transactionTemplate);
}
可供程序根据不同的业务场景选择使用不同的数据源。
网友评论