Add below pom dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<artifactId>1.0.14</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
We can use below tool to generate the mybatis code
https://github.com/spawpaw/mybatis-generator-gui-extension
Configure the datasource
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/flux?useUnicode=true&characterEncoding=utf-8&useOldAliasMetadataBehavior=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
druid.spring.datasource.initialSize=5
druid.spring.datasource.minIdle=5
druid.spring.datasource.maxActive=20
druid.spring.datasource.maxWait=60000
druid.spring.datasource.timeBetweenEvictionRunsMillis=60000
druid.spring.datasource.minEvictableIdleTimeMillis=300000
druid.spring.datasource.validationQuery=SELECT 1 FROM DUAL
druid.spring.datasource.testWhileIdle=true
druid.spring.datasource.testOnBorrow=false
druid.spring.datasource.testOnReturn=false
druid.spring.datasource.poolPreparedStatements=false
druid.spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
druid.spring.datasource.filters=stat,wall,log4j
druid.spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
@Configuration
@MapperScan(basePackages="<the mapper interface class package path>")
public class MyBatisConfigure {
// you can use this env to get the properties from application.properties
// e.g. dbUrl : env.getProperty("spring.datasource.url");
@AutoWried
private Environment env;
// configure datasource
@Bean
public DataSource dataSource() throws Exception {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
// configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
datasource.setFilters(filters);
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
// configure SqlSessionFactory
@Bean
public SqlSessionFactory sqlSessionFactory(DataSrouce ds) throws Exception {
SqlSessionFactory fb = new SqlSessionFactoryBean();
fb.setDataSrouce(ds);
fb.setTypeAliasesPackage("<the domain model POJO package path>");
fb.setMapperLocations(new PathMatchingResourcesPatternResolver().getResources("classpath:<path>/*.xml"));
return fb.getObject();
}
}
Configure another datasource
public enum DatabaseType {
DRUID_DS1,DRUID_DS2
}
public class DatabaseContextHolder {
// each thread holds its own specific datasource
private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();
public static void setDatabaseType(DatabaseType type) {
contextHolder.set(type);
}
public static DatabaseType getDatabaseType() {
return contextHolder.get();
}
}
public class DynamicDataSource extends AbstractRoutingDataSource() {
protected Object determineCurrentLookupKey() {
return DatabaseContextHolder.getDatasourceType();
}
}
Refactor the MyBatisConfigure
@Bean
public DataSource druidDataSource1() throws Exception {
// TODO
}
@Bean
public DataSource druidDataSource2() throws Exception {
// TODO
}
@Bean
@Primary
public DynamicDataSource dataSource(@Qualifier("druidDataSource1") DataSource druidDataSource1,@Qualifier("druidDataSource2") DataSource druidDataSource2) {
Map<Object, Object> targetDataSource = new HashMap<>();
targetDataSource.put(DatabaseType.DRUID_DS1, druidDataSource1);
targetDataSource.put(DatabaseType.DRUID_DS2, druidDataSource2);
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSource);
dataSource.setDefaultTargetDataSource(druidDataSource1);
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
// TODO
}
If you want use druidDataSource2 to query data, you need write the code like below:
@Repository
public class UserDAO {
@Autowired
private UserMapper userMapper;
public List<User> selectById(long uid) {
// choose the data source before query
DatabaseContextHolder.setDatabaseType(DatabaseType.DRUID_DS2);
// TODO
}
}
or create an aspect class to set the datasource:
@Aspect
@Component
public class DataSourceAspect() {
@Before("execution(* <DAO package path>.*.*(..))")
public void setDataSourceKey(JoinPoint point) {
if (point.getTarget() instanceof UserDAO) {
DatabaseContextHolder.setDatabaseType(DatabaseType.DRUID_DS2);
}
}
}
Reference
《Java微服务实战》- 赵计刚