Commit 686750b8 by fengshuonan

合并旧的多数据源修改的分支

parents 9b2a97d4 632c91b9
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
/**
* Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.com)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config.datasource.multi;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import cn.stylefeng.roses.core.mutidatasource.aop.MultiSourceExAop;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* 多数据源配置<br/>
* <p>
* 注:由于引入多数据源,所以让spring事务的aop要在多数据源切换aop的后面
*
* @author stylefeng
* @Date 2017/5/20 21:58
*/
@Configuration
@ConditionalOnProperty(prefix = "guns.muti-datasource", name = "open", havingValue = "true")
@MapperScan(basePackages = {"cn.stylefeng.guns.sys.modular.*.mapper", "cn.stylefeng.guns.generator.modular.mapper", "cn.stylefeng.guns.modular.*.mapper"}, sqlSessionTemplateRef = "gunsSqlSessionTemplate")
public class MultiDataSourceConfig {
/**
* 默认主数据源配置
*/
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DruidProperties druidProperties() {
return new DruidProperties();
}
/**
* 多数据源配置
*/
@Bean
@ConfigurationProperties(prefix = "guns.muti-datasource")
public DruidProperties mutiDataSourceProperties() {
return new DruidProperties();
}
/**
* 主数据源实例
*/
@Primary
@Bean
public DataSource dataSourcePrimary(@Qualifier("druidProperties") DruidProperties druidProperties) {
if (ToolUtil.isOneEmpty(druidProperties, druidProperties.getDataSourceName())) {
throw new IllegalArgumentException("初始化OptionalSqlSessionTemplate错误!请设置spring.datasource.data-source-name属性的值!");
}
return createDataSource(druidProperties.getDataSourceName(), druidProperties);
}
/**
* 第二个数据源实例
*/
@Bean
public DataSource dataSourceBusiness(@Qualifier("mutiDataSourceProperties") DruidProperties mutiDataSourceProperties) {
if (ToolUtil.isOneEmpty(mutiDataSourceProperties, mutiDataSourceProperties.getDataSourceName())) {
throw new IllegalArgumentException("初始化OptionalSqlSessionTemplate错误!请设置spring.muti-datasource.data-source-name属性的值!");
}
return createDataSource(mutiDataSourceProperties.getDataSourceName(), mutiDataSourceProperties);
}
/**
* 多数据源切换的aop
*/
@Bean
public MultiSourceExAop multiSourceExAop() {
return new MultiSourceExAop();
}
/**
* 数据源创建模板
*/
private static DataSource createDataSource(String dataSourceName, DruidProperties druidProperties) {
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
atomikosDataSourceBean.setUniqueResourceName(dataSourceName);
atomikosDataSourceBean.setMaxPoolSize(20);
atomikosDataSourceBean.setBorrowConnectionTimeout(60);
atomikosDataSourceBean.setXaProperties(druidProperties.createProperties());
return atomikosDataSourceBean;
}
}
\ No newline at end of file
/**
* Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.com)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config.datasource.multi;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import cn.stylefeng.roses.core.mutidatasource.mybatis.OptionalSqlSessionTemplate;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 多数据源配置<br/>
* <p>
* 注:由于引入多数据源,所以让spring事务的aop要在多数据源切换aop的后面
*
* @author stylefeng
* @Date 2017/5/20 21:58
*/
@Slf4j
@Configuration
@ConditionalOnProperty(prefix = "guns.muti-datasource", name = "open", havingValue = "true")
public class MultiSqlSessionFactoryConfig {
private final MybatisPlusProperties properties;
private final Interceptor[] interceptors;
private final ResourceLoader resourceLoader;
private final DatabaseIdProvider databaseIdProvider;
private final List<ConfigurationCustomizer> configurationCustomizers;
private final ApplicationContext applicationContext;
public MultiSqlSessionFactoryConfig(MybatisPlusProperties properties,
ObjectProvider<Interceptor[]> interceptorsProvider,
ResourceLoader resourceLoader,
ObjectProvider<DatabaseIdProvider> databaseIdProvider,
ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider,
ApplicationContext applicationContext) {
this.properties = properties;
this.interceptors = interceptorsProvider.getIfAvailable();
this.resourceLoader = resourceLoader;
this.databaseIdProvider = databaseIdProvider.getIfAvailable();
this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
this.applicationContext = applicationContext;
}
/**
* 主sqlSessionFactory
*/
@Primary
@Bean
public SqlSessionFactory sqlSessionFactoryPrimary(@Qualifier("dataSourcePrimary") DataSource dataSource) {
return createSqlSessionFactory(dataSource);
}
/**
* 第二个sqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactoryBusiness(@Qualifier("dataSourceBusiness") DataSource dataSource) {
return createSqlSessionFactory(dataSource);
}
/**
* 多数据源sqlSessionTemplate切换模板
*/
@Bean(name = "gunsSqlSessionTemplate")
public OptionalSqlSessionTemplate gunsSqlSessionTemplate(@Qualifier("sqlSessionFactoryPrimary") SqlSessionFactory sqlSessionFactoryPrimary,
@Qualifier("sqlSessionFactoryBusiness") SqlSessionFactory sqlSessionFactoryBusiness,
@Qualifier("druidProperties") DruidProperties druidProperties,
@Qualifier("mutiDataSourceProperties") DruidProperties mutiDataSourceProperties) {
if (ToolUtil.isOneEmpty(druidProperties, druidProperties.getDataSourceName())) {
throw new IllegalArgumentException("初始化OptionalSqlSessionTemplate错误!请设置spring.datasource.data-source-name属性的值!");
}
if (ToolUtil.isOneEmpty(mutiDataSourceProperties, mutiDataSourceProperties.getDataSourceName())) {
throw new IllegalArgumentException("初始化OptionalSqlSessionTemplate错误!请设置spring.muti-datasource.data-source-name属性的值!");
}
Map<Object, SqlSessionFactory> sqlSessionFactoryMap = new HashMap<>();
sqlSessionFactoryMap.put(druidProperties.getDataSourceName(), sqlSessionFactoryPrimary);
sqlSessionFactoryMap.put(mutiDataSourceProperties.getDataSourceName(), sqlSessionFactoryBusiness);
return new OptionalSqlSessionTemplate(sqlSessionFactoryPrimary, sqlSessionFactoryMap);
}
/**
* 创建数据源
*/
private SqlSessionFactory createSqlSessionFactory(DataSource dataSource) {
try {
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (!ObjectUtils.isEmpty(this.interceptors)) {
factory.setPlugins(this.interceptors);
}
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
GlobalConfig globalConfig = this.properties.getGlobalConfig();
if (this.applicationContext.getBeanNamesForType(MetaObjectHandler.class,
false, false).length > 0) {
MetaObjectHandler metaObjectHandler = this.applicationContext.getBean(MetaObjectHandler.class);
globalConfig.setMetaObjectHandler(metaObjectHandler);
}
//globalConfig中有缓存sqlSessionFactory,目前还没别的办法
SqlSessionFactory sqlSessionFactory = factory.getObject();
globalConfig.signGlobalConfig(sqlSessionFactory);
factory.setGlobalConfig(globalConfig);
return factory.getObject();
} catch (Exception e) {
log.error("初始化SqlSessionFactory错误!", e);
throw new ServiceException(500, "初始化SqlSessionFactory错误!");
}
}
}
\ No newline at end of file
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package cn.stylefeng.guns; package cn.stylefeng.guns;
import cn.stylefeng.roses.core.config.MybatisDataSourceAutoConfiguration;
import cn.stylefeng.roses.core.config.WebAutoConfiguration; import cn.stylefeng.roses.core.config.WebAutoConfiguration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -28,7 +29,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; ...@@ -28,7 +29,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* @author stylefeng * @author stylefeng
* @Date 2017/5/21 12:06 * @Date 2017/5/21 12:06
*/ */
@SpringBootApplication(exclude = {WebAutoConfiguration.class}) @SpringBootApplication(exclude = {WebAutoConfiguration.class, MybatisDataSourceAutoConfiguration.class})
@EnableScheduling @EnableScheduling
public class GunsApplication { public class GunsApplication {
......
...@@ -37,6 +37,8 @@ spring: ...@@ -37,6 +37,8 @@ spring:
password: root password: root
filters: wall,mergeStat filters: wall,mergeStat
data-source-name: gunsdb data-source-name: gunsdb
test-on-borrow: true
test-on-return: true
# 邮件发送配置(改为自己的账号和密码) # 邮件发送配置(改为自己的账号和密码)
mail: mail:
...@@ -48,12 +50,15 @@ spring: ...@@ -48,12 +50,15 @@ spring:
# 多数据源情况的配置 # 多数据源情况的配置
guns: guns:
muti-datasource: muti-datasource:
open: false open: true
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/guns_test_db?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT url: jdbc:mysql://127.0.0.1:3306/guns_test_db?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT
username: root username: root
password: root password: root
data-source-name: otherdb data-source-name: otherdb
test-on-borrow: true
test-on-return: true
# 阿里云短信发送配置 # 阿里云短信发送配置
aliyun: aliyun:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment