配置多数据源,由于不常用就进行了百度,百度了很久(有很多都不能用),加上自己修修改改,终于能用了。那么就废话不多说,直接上代码。
- SpringBoot应用启动类注解:
@MapperScan("com.xxx.mapper")
@SpringBootApplication(scanBasePackages = "com.xxx")
MapperScan是配置到了DAO层的包上。不过这里的MapperScan应该不起作用。配上了也就没必要删掉。
- bootstrap-env.yaml配置Nacos:
spring:
cloud:
nacos:
config:
server-addr: nacos-ip:nacos-port
namespace: my_namespace
group: MY_GROUP
file-extension: yaml
- Nacos配置:
server:
port: 8060
spring:
datasource:
one:
jdbc-url: jdbc:mysql://mysql-host-1:3306/database?useSSL=false&Unicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL&useAffectedRows=true
username: username
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
two:
jdbc-url: jdbc:mysql://mysql-host-2:3306/database?useSSL=false&Unicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL&useAffectedRows=true
username: username
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
one:
database: 0
host: redis-host-1
port: 6379
password: password
two:
database: 1
host: redis-host-2
port: 6379
password: password
这里要注意Nacos配置文件的命名:应用名.yaml
,要加yaml哦,否则可能读不到配置。
4. 数据库Bean的配置:
/**
* 第一个数据源
*/
@Configuration
@MapperScan(basePackages = "com.xxx.mapper.one", sqlSessionFactoryRef = "oneSqlSessionFactory")
public class OneDataSourceConfig {
@Primary // 这个注解意思是主库,只有一个配置类可以加
@Bean("oneDataSource")
@ConfigurationProperties(prefix = "spring.datasource.one")
public DataSource getOneDataSource(){
return DataSourceBuilder.create().build();
}
@Primary
@Bean("oneSqlSessionFactory")
public SqlSessionFactory oneSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/one/*.xml")); //xml的包和DAO层的包,多个数据库建议分开,更清晰。
return bean.getObject();
}
@Primary
@Bean("oneSqlSessionTemplate")
public SqlSessionTemplate oneSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
/**
* 第二个数据源
*/
@Configuration
@MapperScan(basePackages = "com.nucarf.rebate.calculate.mapper.two", sqlSessionFactoryRef = "twoSqlSessionFactory")
public class TwoDataSourceConfig {
@Bean("twoDataSource")
@ConfigurationProperties(prefix = "spring.datasource.two")
public DataSource getTwoDataSource(){
return DataSourceBuilder.create().build();
}
@Bean("twoSqlSessionFactory")
public SqlSessionFactory twoSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/two/*.xml"));
return bean.getObject();
}
@Bean("twoSqlSessionTemplate")
public SqlSessionTemplate twoSqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
- Redis Bean的配置:
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 第一个数据源
*/
@Value("${spring.redis.one.host}")
private String oneHost;
@Value("${spring.redis.one.password}")
private String onePassword;
@Value("${spring.redis.one.port}")
private String onePort;
@Value("${spring.redis.one.database}")
private int oneDatabase;
/**
* 第二个数据源
*/
@Value("${spring.redis.two.host}")
private String twoHost;
@Value("${spring.redis.two.password}")
private String twoPassword;
@Value("${spring.redis.two.port}")
private String twoPort;
@Value("${spring.redis.two.database}")
private int twoDatabase;
//最大空闲连接数
private static final int MAX_IDLE = 8;
//最大连接数
private static final int MAX_TOTAL = 8;
//建立连接最长等待时间
private static final long MAX_WAIT_MILLIS = 10000;
/**
* 配置工厂
*/
public RedisConnectionFactory connectionFactory(String host, int port, String password, int maxIdle,
int maxTotal, long maxWaitMillis, int index) {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName(host);
jedisConnectionFactory.setPort(port);
if (StringUtils.isNotEmpty(password)) {
jedisConnectionFactory.setPassword(password);
}
if (index != 0) {
jedisConnectionFactory.setDatabase(index);
}
jedisConnectionFactory.setPoolConfig(poolConfig(maxIdle, maxTotal, maxWaitMillis, false));
jedisConnectionFactory.afterPropertiesSet();
return jedisConnectionFactory;
}
/**
* 连接池配置
*/
public JedisPoolConfig poolConfig(int maxIdle, int maxTotal, long maxWaitMillis, boolean testOnBorrow) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMaxTotal(maxTotal);
poolConfig.setMaxWaitMillis(maxWaitMillis);
poolConfig.setTestOnBorrow(testOnBorrow);
return poolConfig;
}
/**
* 第一个数据源初始化
*/
@Bean(name = "redisTemplateOne")
public RedisTemplate<String, Object> redisTemplateOne(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(
connectionFactory(oneHost, Integer.parseInt(onePort), onePassword, MAX_IDLE, MAX_TOTAL, MAX_WAIT_MILLIS, oneDatabase));
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* 第二个数据源初始化
*/
@Bean(name = "redisTemplateTwo")
public RedisTemplate<String, Object> redisTemplateTwo(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(
connectionFactory(twoHost, Integer.parseInt(twoPort), twoPassword, MAX_IDLE, MAX_TOTAL, MAX_WAIT_MILLIS, twoDatabase));
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
- 使用
数据库使用没啥说的,直接@Autowired或者@Resource注入就可以了。
Redis使用注入的时候把name写上:
@Resource(name = "redisTemplateOne")
private RedisTemplate<String, Object> redisTemplateOne;