封面圖:山海關,河北秦皇島,2012年6月。
項目中有時會用到多個數據庫,這時候就需要能夠動態切換數據源了,一個比較好的實現是MyBatis-Plus提供的dynamic-datasource-spring-boot-starter,它是一個基於Spring Boot的快速集成多數據源的啓動器。
首先恭喜MyBatis-Plus榮獲2019 年度開源中國最受歡迎的軟件開發工具類 TOP1。
下面通過簡單實例來介紹怎麼使用。
源代碼
https://github.com/wu-boy/spring-boot-demo.git
mybaits模塊中的mybatis-plus-dynamic-datasource模塊。
依賴
首先在Spring Boot項目中引入mybatis-plus-dynamic-datasource依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.5.7</version>
</dependency>
application.yml
需要準備兩個數據庫,配置如下:
spring:
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
dynamic:
primary: postgres
datasource:
postgres:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://127.0.0.1:5432/postgres
username: postgres
password: postgres
test:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://127.0.0.1:5432/test
username: postgres
password: postgres
這是我本機安裝的PostgreSQL數據庫,本次使用postgres和test兩個庫來做測試,兩個庫中均新建user_test表,字段和實體類User一致。
由於DruidDataSourceAutoConfigure會注入一個DataSourceWrapper,其會在原生的spring.datasource下找url,username,password等。而我們動態數據源的配置路徑是變化的,所以需要配置autoconfigure來進行排除。還有種方法是在項目啓動類上排除,如下所示
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
新建實體
@TableName("user_test")
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String username;
private Date createTime;
private Date updateTime;
// 請自行補充get/set
}
新建UserMapper
需要繼承MyBatis-Plus提供的BaseMapper接口,類似於JPA。
public interface UserMapper extends BaseMapper<User> {
}
新建UserService
public interface UserService {
void insertToPostgres(User user);
void insertToTest(User user);
}
@Service
@Transactional
@DS("postgres") // 默認數據庫
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper mapper;
/**
* 保存到Postgres庫
* @param user
*/
@Override
public void insertToPostgres(User user){
mapper.insert(user);
}
/**
* 保存到test庫
* DS註解可以用在類上和方法上,同時存在的話方法註解優先於類上註解
* @param user
*/
@Override
@DS("test")
public void insertToTest(User user){
mapper.insert(user);
}
}
@DS註解表示使用的數據源,在類上@DS(“postgres”)表示使用postgres庫,類中方法insertToTest的註解是@DS(“test”),表示將使用test庫。
@DS註解可以用在類上和方法上,同時存在的話方法註解優先於類上註解。
新建項目啓動類MyBatisPlusApplication
@SpringBootApplication
@MapperScan("com.wu.springboot.demo.mybatis.plus.dynamic.datasource.dao")
public class MyBatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisPlusApplication.class, args);
}
}
@MapperScan註解表示掃描UserMapper所在的dao包。
新建測試類
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserServiceImpl userService;
@Test
public void contextLoads() {
}
@Test
public void insertTest() throws Exception {
User user = new User();
user.setUsername("wusq");
userService.insertToPostgres(user);
userService.insertToTest(user);
}
}
測試類中新建一個User,調用兩個方法,分別將同一個用戶保存到兩個數據庫中。
結束語
這個簡單例子只是介紹了純粹多庫的使用,dynamic-datasource還支持多主多庫、混合配置等,更多功能可以圍觀官網。