找了半天很少有适配多个不同数据源的文章! so自己搞下吧 下面是整个流程和实现有需要优化的评论区提醒下 谢谢!
一、业务流程
二、配置及接口定义
aix-data服务下
案例:
1.增加jar
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2.在application.properties中配置驱动信息和数据源类型
后续可以增加其他驱动信息
#数据源类型 MYSQL,TIDB,CLICKHOUSE aix.data.dbaccess.dbtype=MYSQL # 驱动配置信息 spring.datasource.mysql.jdbcUrl=jdbc:mysql://bj.paas.sensetime.com:39605/aix_data?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull spring.datasource.mysql.username=devadmin spring.datasource.mysql.password=wzjydAdmin899 spring.datasource.mysql.driverClassName = org.mariadb.jdbc.Driver # tidb驱动配置信息 spring.datasource.tidb.jdbcUrl=jdbc:mysql://bj.paas.sensetime.com:39605/aix_data?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull spring.datasource.tidb.username=devadmin spring.datasource.tidb.password=wzjydAdmin899 spring.datasource.tidb.driverClassName = org.mariadb.jdbc.Driver # clichouse驱动配置信息 spring.datasource.clickhouse.jdbcUrl=jdbc:clickhouse://10.4.50.16:8123/aix_data spring.datasource.clickhouse.driverClassName = ru.yandex.clickhouse.ClickHouseDriver
3.配置数据源和映射位置(不同数据源配置方式不同)
package com.sensetime.idea.aix.data.config;
import com.sensetime.idea.aix.data.database.enums.DataSourceType;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.util.Locale;
@Slf4j
@Configuration
@EnableConfigurationProperties
public class DatabaseConfig {
static final String SQL_MAPPER_TMP_FLAG="${DST}";
static final String SQL_MAPPER_TMP="classpath*:mapper/${DST}/*.xml";
@Value("${aix.data.dbaccess.dbtype}")
private String dataSourceType;
private String sqlMapperPath;
@Bean(name = "dataSourceConfig")
public DataSource dataSource() {
sqlMapperPath = SQL_MAPPER_TMP.replace(SQL_MAPPER_TMP_FLAG,dataSourceType.toLowerCase());
if (DataSourceType.MYSQL.getValue().equals(dataSourceType)) {
return mysqlSourceConfig();
} else if (DataSourceType.TIDB.getValue().equals(dataSourceType)) {
return tidbSourceConfig();
} else if (DataSourceType.CLICKHOUSE.getValue().equals(dataSourceType)) {
return clickHouseDataSourceConfig();
}else{
log.error("The DataSource Type[{}] is not supported or configured!",dataSourceType);
return null;
}
}
@ConfigurationProperties(prefix = "spring.datasource.mysql")
@Bean
public DataSource mysqlSourceConfig() {
return DataSourceBuilder.create().build();
}
@ConfigurationProperties(prefix = "spring.datasource.tidb")
@Bean
public DataSource tidbSourceConfig() {
return DataSourceBuilder.create().build();
}
@ConfigurationProperties(prefix = "spring.datasource.clickhouse")
@Bean
public DataSource clickHouseDataSourceConfig() {
return DataSourceBuilder.create().build();
}
@Bean(name = "SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSourceConfig") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(sqlMapperPath));
return bean.getObject();
}
@Bean(name = "SqlSessionTemplate")
public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "TransactionManager")
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
4.定义DBAccessor接口
package com.sensetime.idea.aix.data.database.service;
import com.sensetime.idea.aix.common.data.core.entity.Event;
import com.sensetime.idea.aix.common.data.core.entity.Pass;
import com.sensetime.idea.aix.data.database.dao.entity.SysConfig;
import java.util.List;
import java.util.Map;
public interface DBAccessor {
public Integer insertEvent(Event event);
public List<Event> listEvent(Map<String, Object> params);
public Integer listCountEvent(Map<String, Object> params);
public Event selectDetailByPrimaryKeyEvent(Map<String, Object> params);
public Integer deleteByPrimaryKeysEvent(Map<String, Object> params);
public Integer insertPass(Pass pass);
public Integer deleteByPrimaryKeysPass(Map<String, Object> params);
public List<Pass> listPass(Map<String, Object> params);
public Integer listCountPass(Map<String, Object> params);
public Pass selectDetailByPrimaryKeyPass(Map<String, Object> params);
public Integer deleteByTenantIdPass(Map<String, Object> params);
public int insertSysConfig(SysConfig record);
public int updateByPrimaryKeySysConfig(SysConfig record);
public SysConfig selectByPrimaryKeySysConfig(String tenantId);
}
5.根据项目所需数据源创建Impl实现DBAccessor接口类
已创建MySQLAccessor、TidbAccessor、ClickHouseAccessor
6.配置DBAccessorFactory 根据配置文件中的aix.data.source.type实例化其中一个实现类
package com.sensetime.idea.aix.data.database.factory;
import com.sensetime.idea.aix.data.database.enums.DataSourceType;
import com.sensetime.idea.aix.data.database.service.DBAccessor;
import com.sensetime.idea.aix.data.database.service.impl.MySQLAccessor;
import com.sensetime.idea.aix.data.database.service.impl.TidbAccessor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DBAccessorFactory {
@Value("${data.source.type}")
private String dataSourceType;
@Bean
public DBAccessor createDBAccessor() {
if (DataSourceType.MYSQL.getValue().equals(dataSourceType)) {
return new MySQLAccessor();
} else if (DataSourceType.TIDB.getValue().equals(dataSourceType)) {
return new TidbAccessor();
} else if (DataSourceType.CLICKHOUSE.getValue().equals(dataSourceType)) {
return new ClickHouseAccessor();
} else {
throw new IllegalArgumentException("Invalid DB accessor type");
}
// 其他数据库类型的处理逻辑...
// else{}
}
}
6.aix-store和aix-management模块中调用DBAccessor接口