(1)dynamic-datasource-spring-boot-starter 是一个基于 springboot 的快速集成多数据源的启动器。其支持 Jdk 1.7+,SpringBoot 1.4.x 1.5.x 2.0.x。
注意:该插件可以不依赖 MyBatis-Plus,可以独立使用。
(2)它主要用于读写分离,一主多从的环境。(当然也可以纯粹当成多库使用)
一主多从的环境下数据库分工:
<!-- 多数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
提示:
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/hangge?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
slave_1:
url: jdbc:mysql://xx.xx.xx.xx:3307/hangge?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
slave_2:
url: jdbc:mysql://xx.xx.xx.xx:3308/hangge?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
spring:
datasource:
dynamic:
datasource:
master_1:
master_2:
slave_1:
slave_2:
slave_3:
spring:
datasource:
dynamic:
datasource:
mysql:
oracle:
sqlserver:
postgresql:
h2:
spring:
datasource:
dynamic:
datasource:
master:
slave_1:
slave_2:
oracle_1:
oracle_2:
@Service
@DS("slave")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Map<String, Object>> selectAll() {
return jdbcTemplate.queryForList("select * from user");
}
@Override
@DS("slave_1")
public List<Map<String, Object>> selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}
@DS("master")
public interface UserMapper {
@Insert("INSERT INTO user (name,age) values (#{name},#{age})")
boolean addUser(@Param("name") String name, @Param("age") Integer age);
@Update("UPDATE user set name=#{name}, age=#{age} where id =#{id}")
boolean updateUser(@Param("id") Integer id, @Param("name") String name, @Param("age") Integer age);
@Delete("DELETE from user where id =#{id}")
boolean deleteUser(@Param("id") Integer id);
@Select("SELECT * FROM user")
@DS
List<User> selectAll();
}
(1)假设我们有 hangge 与 hangge2 两个数据库,两个库中都有 user_info 这张表(不过两个库里数据不一样):
(2)在配置文件中一个设置为主库,一个设置为从库:
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
datasource:
master:
url: jdbc:mysql://localhost:3306/hangge?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
slave:
url: jdbc:mysql://localhost:3306/hangge2?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
(3)默认情况下,如果不做额外配置的话,都是操作主库:
@RestController
public class HelloController {
@Autowired
UserInfoService userInfoService;
@GetMapping("/test")
public List<UserInfo> test() {
return userInfoService.list();
}
}
(4)使用 @DS 切换数据源,这里我们将 UserInfoService 数据源切换成从库。再次进行查询,可以发现数据源确实发生变化。
@DS("slave")
public interface UserInfoService extends IService<UserInfo> {
}
(1)如果数据源指定的是一个分组,且该分组下有多个数据库,那么会自动进行负载均衡。比如我们在上面样例上稍作修改,配置了两个从库:
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
datasource:
master:
url: jdbc:mysql://localhost:3306/hangge?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
slave_1:
url: jdbc:mysql://localhost:3306/hangge2?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
slave_2:
url: jdbc:mysql://localhost:3306/hangge?serverTimezone=Asia/Shanghai
username: root
password: hangge1234
type: com.alibaba.druid.pool.DruidDataSource
(2)UserInfoService 同样通过 @DS 注解指定使用 slave 这个分组:
@DS("slave")
public interface UserInfoService extends IService<UserInfo> {
}
(3)多次刷新浏览器,可以发现数据轮流从两个库中获取,说明负载均衡生效了。