Commit a408909a by fengshuonan

更新数据源配置方式

parent 686750b8
......@@ -16,7 +16,7 @@ USE guns;
Target Server Version : 50724
File Encoding : 65001
Date: 11/06/2019 14:01:41
Date: 12/06/2019 17:17:50
*/
SET NAMES utf8mb4;
......@@ -28,11 +28,12 @@ SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `database_info`;
CREATE TABLE `database_info` (
`db_id` bigint(20) NOT NULL COMMENT '主键id',
`db_name` varchar(255) NOT NULL COMMENT '数据库名称',
`db_name` varchar(255) NOT NULL COMMENT '数据库名称(英文名称)',
`jdbc_driver` varchar(255) NOT NULL COMMENT 'jdbc的驱动类型',
`user_name` varchar(255) NOT NULL COMMENT '数据库连接的账号',
`password` varchar(255) NOT NULL COMMENT '数据库连接密码',
`jdbc_url` varchar(2000) NOT NULL COMMENT 'jdbc的url',
`remarks` varchar(255) DEFAULT NULL COMMENT '备注,摘要',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`db_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='数据库信息表';
......@@ -41,7 +42,7 @@ CREATE TABLE `database_info` (
-- Records of database_info
-- ----------------------------
BEGIN;
INSERT INTO `database_info` VALUES (1, '默认数据库', 'com.mysql.jdbc.Driver', 'root', 'root', 'jdbc:mysql://127.0.0.1:3306/guns?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT', '2019-05-11 13:51:19');
INSERT INTO `database_info` VALUES (1, 'master', 'com.mysql.jdbc.Driver', 'root', 'root', 'jdbc:mysql://127.0.0.1:3306/guns?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT', 'Guns启动的数据源', '2019-05-11 13:51:19');
COMMIT;
-- ----------------------------
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-vip</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>guns-base-db-container</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--基础组件-->
<dependency>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-base</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
package cn.stylefeng.datasource.container.context;
import cn.stylefeng.datasource.container.dao.DataBaseInfoDao;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 数据源的上下文容器(单例)
*
* @author fengshuonan
* @date 2019-06-12-13:37
*/
public class DataSourceContext {
/**
* 主数据源名称
*/
public static final String MASTER_DATASOURCE_NAME = "master";
/**
* 数据源容器
*/
private static Map<String, DataSource> DATA_SOURCES = new ConcurrentHashMap<>();
/**
* 初始化所有dataSource
*
* @author fengshuonan
* @Date 2019-06-12 13:48
*/
public static void initDataSource(DruidProperties masterDataSourceProperties) {
//从数据库中获取所有的数据源信息
DataBaseInfoDao dataBaseInfoDao = new DataBaseInfoDao(masterDataSourceProperties);
Map<String, DruidProperties> allDataBaseInfo = dataBaseInfoDao.getAllDataBaseInfo();
//根据数据源信息初始化所有的DataSource
for (Map.Entry<String, DruidProperties> entry : allDataBaseInfo.entrySet()) {
String dbName = entry.getKey();
DruidProperties druidProperties = entry.getValue();
//通过property创建DataSource
DataSource dataSource = createDataSource(dbName, druidProperties);
DATA_SOURCES.put(dbName, dataSource);
}
}
/**
* 新增datasource
*
* @author fengshuonan
* @Date 2019-06-12 14:51
*/
public void addDataSource(String dbName, DataSource dataSource) {
DATA_SOURCES.put(dbName, dataSource);
}
/**
* 获取数据源
*
* @author fengshuonan
* @Date 2019-06-12 13:50
*/
public static Map<String, DataSource> getDataSources() {
return DATA_SOURCES;
}
/**
* 数据源创建模板
*/
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;
}
}
package cn.stylefeng.datasource.container.context;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* mybatis的sqlSessionFactory的上下文容器(单例)
*
* @author fengshuonan
* @date 2019-06-12-13:37
*/
public class SqlSessionFactoryContext {
private static Map<Object, SqlSessionFactory> sqlSessionFactories = new ConcurrentHashMap<>();
/**
* 添加sqlSessionFactory
*
* @author fengshuonan
* @Date 2019-06-12 15:28
*/
public static void addSqlSessionFactory(String name, SqlSessionFactory sqlSessionFactory) {
sqlSessionFactories.put(name, sqlSessionFactory);
}
/**
* 获取所有的sqlSessionFactory
*
* @author fengshuonan
* @Date 2019-06-12 13:49
*/
public static Map<Object, SqlSessionFactory> getSqlSessionFactorys() {
return sqlSessionFactories;
}
}
package cn.stylefeng.datasource.container.dao;
import cn.stylefeng.datasource.container.exception.DataSourceInitException;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
/**
* 操作数据源信息的dao
*
* @author fengshuonan
* @date 2019-06-12-14:02
*/
@Slf4j
public class DataBaseInfoDao {
private String MYSQL_SQL_LIST = "select db_name,jdbc_driver,jdbc_url,user_name,password from database_info";
private DruidProperties druidProperties;
public DataBaseInfoDao(DruidProperties druidProperties) {
this.druidProperties = druidProperties;
}
/**
* 查询所有数据源列表
*
* @author fengshuonan
* @Date 2019-05-04 20:30
*/
public Map<String, DruidProperties> getAllDataBaseInfo() {
Map<String, DruidProperties> dataSourceList = new HashMap<>();
try {
Class.forName(druidProperties.getDriverClassName());
Connection conn = DriverManager.getConnection(
druidProperties.getUrl(), druidProperties.getUsername(), druidProperties.getPassword());
PreparedStatement preparedStatement = conn.prepareStatement(MYSQL_SQL_LIST);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
DruidProperties druidProperties = createDruidProperties(resultSet);
String dbName = resultSet.getString("db_name");
dataSourceList.put(dbName, druidProperties);
}
return dataSourceList;
} catch (Exception ex) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.QUERY_DATASOURCE_INFO_ERROR);
}
}
/**
* 通过查询结果组装druidProperties
*
* @author fengshuonan
* @Date 2019-06-12 14:22
*/
private DruidProperties createDruidProperties(ResultSet resultSet) {
DruidProperties druidProperties = new DruidProperties();
druidProperties.setTestOnBorrow(true);
druidProperties.setTestOnReturn(true);
try {
druidProperties.setDriverClassName(resultSet.getString("jdbc_driver"));
druidProperties.setUrl(resultSet.getString("jdbc_url"));
druidProperties.setUsername(resultSet.getString("user_name"));
druidProperties.setPassword(resultSet.getString("password"));
} catch (SQLException e) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.QUERY_DATASOURCE_INFO_ERROR);
}
return druidProperties;
}
}
package cn.stylefeng.datasource.container.exception;
import cn.stylefeng.roses.kernel.model.exception.AbstractBaseExceptionEnum;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
/**
* 数据源容器初始化失败异常
*
* @author fengshuonan
* @date 2019-06-12-13:53
*/
public class DataSourceInitException extends ServiceException {
public DataSourceInitException(AbstractBaseExceptionEnum exception) {
super(exception);
}
public enum ExEnum implements AbstractBaseExceptionEnum {
DATA_SOURCE_READ_ERROR(500, "获取主数据源异常"),
INIT_DATA_SOURCE_ERROR(500, "初始化数据源异常"),
QUERY_DATASOURCE_INFO_ERROR(500, "查询数据库中数据源信息错误");
ExEnum(int code, String message) {
this.code = code;
this.message = message;
}
private Integer code;
private String message;
@Override
public Integer getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}
}
package cn.stylefeng.datasource.container.listener;
import cn.stylefeng.datasource.container.context.DataSourceContext;
import cn.stylefeng.datasource.container.exception.DataSourceInitException;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
/**
* 初始化数据源
*
* @author fengshuonan
* @Date 2019-06-12 13:35
*/
@Slf4j
public class DataSourceInitializer implements ApplicationListener<ApplicationPreparedEvent>, Ordered {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public void onApplicationEvent(ApplicationPreparedEvent event) {
//获取数据源配置
DruidProperties druidProperties = event.getApplicationContext().getBean(DruidProperties.class);
if (druidProperties == null) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.DATA_SOURCE_READ_ERROR);
}
//初始化数据源容器
try {
DataSourceContext.initDataSource(druidProperties);
} catch (Exception e) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.INIT_DATA_SOURCE_ERROR);
}
}
}
......@@ -25,8 +25,9 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-base-db-container</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
......
......@@ -13,15 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config.datasource.multi;
package cn.stylefeng.guns.sys.config.datasource;
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;
......@@ -29,6 +26,8 @@ import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import static cn.stylefeng.datasource.container.context.DataSourceContext.MASTER_DATASOURCE_NAME;
/**
* 多数据源配置<br/>
* <p>
......@@ -38,9 +37,7 @@ import javax.sql.DataSource;
* @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 {
public class DataSourceConfig {
/**
* 默认主数据源配置
......@@ -53,35 +50,20 @@ public class MultiDataSourceConfig {
}
/**
* 多数据源配置
*/
@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);
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
atomikosDataSourceBean.setUniqueResourceName(MASTER_DATASOURCE_NAME);
atomikosDataSourceBean.setMaxPoolSize(20);
atomikosDataSourceBean.setBorrowConnectionTimeout(60);
atomikosDataSourceBean.setXaProperties(druidProperties.createProperties());
return atomikosDataSourceBean;
}
/**
......@@ -92,16 +74,4 @@ public class MultiDataSourceConfig {
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
......@@ -2,17 +2,23 @@ package cn.stylefeng.guns.sys.config.datasource;
import cn.stylefeng.guns.sys.core.shiro.ShiroKit;
import cn.stylefeng.roses.core.metadata.CustomMetaObjectHandler;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* mp的插件拓展
* mp的插件拓展和资源扫描
*
* @author fengshuonan
* @Date 2019/5/10 21:33
*/
@Configuration
public class MpPluginsConfig {
@MapperScan(basePackages = {"cn.stylefeng.guns.sys.modular.*.mapper",
"cn.stylefeng.guns.generator.modular.mapper",
"cn.stylefeng.guns.modular.*.mapper",
"cn.stylefeng.guns.sms.modular.mapper",
"cn.stylefeng.guns.oauth.modular.mapper"})
public class PluginsConfig {
/**
* 拓展核心包中的字段包装器
......
/**
* 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;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* 多数据源配置,多数据源配置因为和单数据源冲突,所以现在默认版本删除了多数据源配置
* <p>
* 可参考 https://gitee.com/stylefeng/guns/tree/multi-datasource/
*
* @author stylefeng
* @Date 2017/5/20 21:58
*/
@Configuration
@ConditionalOnProperty(prefix = "guns.muti-datasource", name = "open", havingValue = "false", matchIfMissing = true)
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan(basePackages = {"cn.stylefeng.guns.sys.modular.*.mapper",
"cn.stylefeng.guns.generator.modular.mapper",
"cn.stylefeng.guns.modular.*.mapper",
"cn.stylefeng.guns.sms.modular.mapper",
"cn.stylefeng.guns.oauth.modular.mapper"})
public class SingleDataSourceConfig {
}
......@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config.datasource.multi;
package cn.stylefeng.guns.sys.config.datasource;
import cn.stylefeng.datasource.container.context.DataSourceContext;
import cn.stylefeng.datasource.container.context.SqlSessionFactoryContext;
import cn.stylefeng.datasource.container.exception.DataSourceInitException;
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;
......@@ -31,20 +32,18 @@ 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;
import static cn.stylefeng.datasource.container.context.DataSourceContext.MASTER_DATASOURCE_NAME;
/**
* 多数据源配置<br/>
* <p>
......@@ -55,33 +54,24 @@ import java.util.Map;
*/
@Slf4j
@Configuration
@ConditionalOnProperty(prefix = "guns.muti-datasource", name = "open", havingValue = "true")
public class MultiSqlSessionFactoryConfig {
public class SqlSessionFactoryConfig {
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) {
public SqlSessionFactoryConfig(MybatisPlusProperties properties,
ObjectProvider<Interceptor[]> interceptorsProvider,
ObjectProvider<DatabaseIdProvider> databaseIdProvider,
ApplicationContext applicationContext) {
this.properties = properties;
this.interceptors = interceptorsProvider.getIfAvailable();
this.resourceLoader = resourceLoader;
this.databaseIdProvider = databaseIdProvider.getIfAvailable();
this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
this.applicationContext = applicationContext;
}
......@@ -95,37 +85,43 @@ public class MultiSqlSessionFactoryConfig {
}
/**
* 第二个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属性的值!");
@Qualifier("druidProperties") DruidProperties druidProperties) {
//初始化数据源容器
try {
DataSourceContext.initDataSource(druidProperties);
} catch (Exception e) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.INIT_DATA_SOURCE_ERROR);
}
if (ToolUtil.isOneEmpty(mutiDataSourceProperties, mutiDataSourceProperties.getDataSourceName())) {
throw new IllegalArgumentException("初始化OptionalSqlSessionTemplate错误!请设置spring.muti-datasource.data-source-name属性的值!");
//先添加主数据源
SqlSessionFactoryContext.addSqlSessionFactory(MASTER_DATASOURCE_NAME, sqlSessionFactoryPrimary);
//获取数据库的数据源
Map<String, DataSource> dataSources = DataSourceContext.getDataSources();
//创建其他sqlSessionFactory
for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
String dbName = entry.getKey();
DataSource dataSource = entry.getValue();
//如果是主数据源,跳过,否则会冲突
if (MASTER_DATASOURCE_NAME.equals(dbName)) {
continue;
} else {
SqlSessionFactory sqlSessionFactory = createSqlSessionFactory(dataSource);
SqlSessionFactoryContext.addSqlSessionFactory(dbName, sqlSessionFactory);
}
}
Map<Object, SqlSessionFactory> sqlSessionFactoryMap = new HashMap<>();
sqlSessionFactoryMap.put(druidProperties.getDataSourceName(), sqlSessionFactoryPrimary);
sqlSessionFactoryMap.put(mutiDataSourceProperties.getDataSourceName(), sqlSessionFactoryBusiness);
return new OptionalSqlSessionTemplate(sqlSessionFactoryPrimary, sqlSessionFactoryMap);
return new OptionalSqlSessionTemplate(sqlSessionFactoryPrimary, SqlSessionFactoryContext.getSqlSessionFactorys());
}
/**
* 创建数据源
* 创建SqlSessionFactory
*/
private SqlSessionFactory createSqlSessionFactory(DataSource dataSource) {
try {
......
package cn.stylefeng.guns.generator.modular.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
......@@ -17,6 +15,7 @@ import java.io.Serializable;
* @since 2019-05-11
*/
@TableName("database_info")
@Data
public class DatabaseInfo implements Serializable {
private static final long serialVersionUID = 1L;
......@@ -58,78 +57,15 @@ public class DatabaseInfo implements Serializable {
private String jdbcUrl;
/**
* 备注
*/
@TableField("remarks")
private String remarks;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
public Long getDbId() {
return dbId;
}
public void setDbId(Long dbId) {
this.dbId = dbId;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getJdbcDriver() {
return jdbcDriver;
}
public void setJdbcDriver(String jdbcDriver) {
this.jdbcDriver = jdbcDriver;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getJdbcUrl() {
return jdbcUrl;
}
public void setJdbcUrl(String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "DatabaseInfo{" +
"dbId=" + dbId +
", dbName=" + dbName +
", jdbcDriver=" + jdbcDriver +
", userName=" + userName +
", password=" + password +
", jdbcUrl=" + jdbcUrl +
", createTime=" + createTime +
"}";
}
}
......@@ -10,12 +10,13 @@
<result column="user_name" property="userName"/>
<result column="password" property="password"/>
<result column="jdbc_url" property="jdbcUrl"/>
<result column="remarks" property="remarks"/>
<result column="create_time" property="createTime"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
db_id AS "dbId", db_name AS "dbName", jdbc_driver AS "jdbcDriver", user_name AS "userName", password AS "password", jdbc_url AS "jdbcUrl", create_time AS "createTime"
db_id AS "dbId", db_name AS "dbName", jdbc_driver AS "jdbcDriver", user_name AS "userName", password AS "password", jdbc_url AS "jdbcUrl", remarks AS "remarks", create_time AS "createTime"
</sql>
<select id="customList" resultType="cn.stylefeng.guns.generator.modular.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam">
......
......@@ -15,7 +15,7 @@
*/
package cn.stylefeng.guns.modular.demos.controller;
import cn.stylefeng.guns.modular.demos.service.TestMultiDbService;
import cn.stylefeng.guns.modular.demos.service.TranTestService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -30,16 +30,22 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@RequestMapping("/multi")
public class TestMultiController extends BaseController {
public class TestMultiTranController extends BaseController {
@Autowired
private TestMultiDbService testMultiDbService;
private TranTestService testMultiDbService;
@RequestMapping("")
public Object auth() {
@RequestMapping("/success")
public Object testSuccess() {
testMultiDbService.beginTest();
return SuccessResponseData.success();
}
@RequestMapping("/fail")
public Object testFail() {
testMultiDbService.beginTestFail();
return SuccessResponseData.success();
}
}
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <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.modular.demos.controller;
import cn.stylefeng.guns.modular.demos.service.TranTestService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试单数据源回滚
*
* @author stylefeng
* @Date 2018/7/20 23:39
*/
@RestController
@RequestMapping("/single")
public class TestSingleTranController extends BaseController {
@Autowired
private TranTestService testMultiDbService;
@RequestMapping("/success")
public Object testSuccess() {
testMultiDbService.testSingleSuccess();
return SuccessResponseData.success();
}
@RequestMapping("/fail")
public Object testFail() {
testMultiDbService.testSingleFail();
return SuccessResponseData.success();
}
}
......@@ -25,7 +25,7 @@ public class GunsDbService extends ServiceImpl<UserMapper, User> {
@Autowired
private UserService userService;
@DataSource(name = "gunsdb")
@DataSource(name = "master")
public void gunsdb() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
......
......@@ -25,7 +25,7 @@ public class OtherDbService extends ServiceImpl<UserMapper, User> {
@Autowired
private UserService userService;
@DataSource(name = "otherdb")
@DataSource(name = "test")
public void otherdb() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
......
package cn.stylefeng.guns.modular.demos.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 测试多数据源回滚的例子
* </p>
*
* @author stylefeng
* @since 2018-12-07
*/
@Service
public class TestMultiDbService {
@Autowired
private GunsDbService gunsDbService;
@Autowired
private OtherDbService otherDbService;
@Transactional(rollbackFor = Exception.class)
public void beginTest() {
gunsDbService.gunsdb();
otherDbService.otherdb();
// int i = 1 / 0;
}
}
package cn.stylefeng.guns.modular.demos.service;
import cn.hutool.core.util.RandomUtil;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
* <p>
* 测试数据源能否回滚的例子
* </p>
*
* @author stylefeng
* @since 2018-12-07
*/
@Service
public class TranTestService {
@Autowired
private GunsDbService gunsDbService;
@Autowired
private OtherDbService otherDbService;
@Transactional(rollbackFor = Exception.class)
public void testSingleSuccess() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
user.setPassword(RandomUtil.randomString(5));
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
user.setCreateUser(1L);
user.setUpdateUser(1L);
gunsDbService.save(user);
User user2 = new User();
user2.setAccount(RandomUtil.randomString(5));
user2.setPassword(RandomUtil.randomString(5));
user2.setCreateTime(new Date());
user2.setUpdateTime(new Date());
user2.setCreateUser(1L);
user2.setUpdateUser(1L);
gunsDbService.save(user2);
}
@Transactional(rollbackFor = Exception.class)
public void testSingleFail() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
user.setPassword(RandomUtil.randomString(5));
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
user.setCreateUser(1L);
user.setUpdateUser(1L);
gunsDbService.save(user);
User user2 = new User();
user2.setAccount(RandomUtil.randomString(5));
user2.setPassword(RandomUtil.randomString(5));
user2.setCreateTime(new Date());
user2.setUpdateTime(new Date());
user2.setCreateUser(1L);
user2.setUpdateUser(1L);
gunsDbService.save(user2);
int i = 1 / 0;
}
@Transactional(rollbackFor = Exception.class)
public void beginTest() {
gunsDbService.gunsdb();
otherDbService.otherdb();
}
@Transactional(rollbackFor = Exception.class)
public void beginTestFail() {
gunsDbService.gunsdb();
otherDbService.otherdb();
int i = 1 / 0;
}
}
......@@ -6,7 +6,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
#SQLServer配置
#spring:
......@@ -16,7 +15,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
#PostgreSQL配置
#spring:
......@@ -26,7 +24,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
# Mysql数据库
spring:
......@@ -36,7 +33,6 @@ spring:
username: root
password: root
filters: wall,mergeStat
data-source-name: gunsdb
# 邮件发送配置(改为自己的账号和密码)
mail:
......@@ -45,16 +41,6 @@ spring:
username: sn93@qq.com
password: xxxpassword
# 多数据源情况的配置
guns:
muti-datasource:
open: false
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
username: root
password: root
data-source-name: otherdb
# 阿里云短信发送配置
aliyun:
sms:
......
......@@ -6,7 +6,6 @@
# username: GUNS
# password: GUNS
# filters: wall,mergeStat
# data-source-name: gunsdb
#SQLServer配置
#spring:
......@@ -16,7 +15,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
#PostgreSQL配置
#spring:
......@@ -26,7 +24,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
# Mysql数据库
spring:
......@@ -36,9 +33,6 @@ spring:
username: root
password: root
filters: wall,mergeStat
data-source-name: gunsdb
test-on-borrow: true
test-on-return: true
# 邮件发送配置(改为自己的账号和密码)
mail:
......@@ -47,19 +41,6 @@ spring:
username: sn93@qq.com
password: xxxpassword
# 多数据源情况的配置
guns:
muti-datasource:
open: true
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
username: root
password: root
data-source-name: otherdb
test-on-borrow: true
test-on-return: true
# 阿里云短信发送配置
aliyun:
sms:
......
......@@ -21,6 +21,7 @@
<modules>
<module>guns-base</module>
<module>guns-base-db-container</module>
<module>guns-base-sms</module>
<module>guns-base-email</module>
<module>guns-base-timers</module>
......@@ -63,7 +64,7 @@
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-core</artifactId>
<version>1.2.2</version>
<version>1.2.4</version>
</dependency>
<!--数据库驱动,可根据自己需要自行删减-->
......
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