diff --git a/mybatis-plus-multi-datasource.md b/mybatis-plus-multi-datasource.md
new file mode 100644
index 0000000..3dc7279
--- /dev/null
+++ b/mybatis-plus-multi-datasource.md
@@ -0,0 +1,336 @@
+# MyBatis Plus 多数据源配置与使用文档
+
+## 1. 环境与依赖
+
+### 1.1 环境要求
+- Spring Boot 3.x
+- MyBatis Plus 3.5.x
+- Java 21
+
+### 1.2 依赖添加
+添加 MyBatis Plus 动态数据源依赖:
+
+```xml
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+ 3.6.1
+
+```
+
+## 2. 配置文件修改
+
+### 2.1 主配置文件
+配置多数据源:
+
+```yaml
+spring:
+ datasource:
+ dynamic:
+ primary: master
+ strict: false
+ datasource:
+ master:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://117.72.94.232:53306/tacit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
+ username: root
+ password: fU44GFH5
+ slave:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/tacit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
+ username: root
+ password: root123
+```
+
+### 2.2 配置说明
+| 配置项 | 说明 | 示例值 |
+|-------|------|-------|
+| primary | 默认数据源名称 | master |
+| strict | 是否启用严格模式 | false |
+| datasource.master | 主数据源配置 | - |
+| datasource.slave | 从数据源配置 | - |
+| driver-class-name | 数据库驱动类名 | com.mysql.cj.jdbc.Driver |
+| url | 数据库连接地址 | jdbc:mysql://117.72.94.232:53306/tacit |
+| username | 数据库用户名 | root |
+| password | 数据库密码 | password |
+
+## 3. 代码实现
+
+### 3.1 实体类
+创建测试实体类 `TestEntity`:
+
+```java
+package com.tacit.admin.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.tacit.common.entity.Base;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("test") // 指定数据库表名
+public class TestEntity extends Base {
+ @TableId(type = IdType.AUTO)
+ private Long id;
+ private String name; // 姓名
+ private Integer age; // 年龄
+ private String email; // 邮箱
+}
+```
+
+### 3.2 Mapper 接口
+创建 Mapper 接口 `TestMapper`:
+
+```java
+package com.tacit.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.tacit.admin.entity.TestEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper // 标记为 MyBatis Mapper 接口
+public interface TestMapper extends BaseMapper {
+ // 继承 BaseMapper 后,自动拥有 CRUD 方法
+}
+```
+
+### 3.3 Service 接口
+创建 Service 接口 `TestService`:
+
+```java
+package com.tacit.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.tacit.admin.entity.TestEntity;
+
+public interface TestService extends IService {
+ /**
+ * 根据 ID 查询测试数据
+ * @param id 主键 ID
+ * @return TestEntity
+ */
+ TestEntity getTestById(Long id);
+}
+```
+
+### 3.4 Service 实现类
+
+#### 3.4.1 主数据源实现类
+创建主数据源 Service 实现类 `TestMasterServiceImpl`:
+
+```java
+package com.tacit.admin.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.mapper.TestMapper;
+import com.tacit.admin.service.TestService;
+import org.springframework.stereotype.Service;
+
+@Service("testMasterService") // 指定 Bean 名称,方便注入
+@DS("master") // 指定使用主数据源
+public class TestMasterServiceImpl extends ServiceImpl implements TestService {
+
+ /**
+ * 使用主数据源查询数据
+ * @param id 主键 ID
+ * @return TestEntity
+ */
+ @Override
+ public TestEntity getTestById(Long id) {
+ return getById(id); // 调用父类方法,自动使用主数据源
+ }
+}
+```
+
+#### 3.4.2 从数据源实现类
+创建从数据源 Service 实现类 `TestSlaveServiceImpl`:
+
+```java
+package com.tacit.admin.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.mapper.TestMapper;
+import com.tacit.admin.service.TestService;
+import org.springframework.stereotype.Service;
+
+@Service("testSlaveService") // 指定 Bean 名称,方便注入
+@DS("slave") // 指定使用从数据源
+public class TestSlaveServiceImpl extends ServiceImpl implements TestService {
+
+ /**
+ * 使用从数据源查询数据
+ * @param id 主键 ID
+ * @return TestEntity
+ */
+ @Override
+ public TestEntity getTestById(Long id) {
+ return getById(id); // 调用父类方法,自动使用从数据源
+ }
+}
+```
+
+### 3.5 控制器
+创建测试控制器 `MultiDatasourceTestController`:
+
+```java
+package com.tacit.admin.controller;
+
+import com.tacit.common.entity.ResponseResult;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.service.TestService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/multi-datasource")
+@Tag(name = "多数据源测试接口", description = "用于测试多数据源的接口")
+public class MultiDatasourceTestController {
+
+ @Autowired
+ @Qualifier("testMasterService") // 注入主数据源 Service
+ private TestService testMasterService;
+
+ @Autowired
+ @Qualifier("testSlaveService") // 注入从数据源 Service
+ private TestService testSlaveService;
+
+ @Operation(summary = "使用主数据源创建测试数据", description = "使用主数据源创建测试数据")
+ @PostMapping("/master/create")
+ public ResponseResult createTestDataWithMaster(@RequestBody TestEntity testEntity) {
+ testMasterService.save(testEntity); // 使用主数据源保存数据
+ return ResponseResult.success(testEntity);
+ }
+
+ @Operation(summary = "使用主数据源查询测试数据", description = "使用主数据源查询测试数据")
+ @GetMapping("/master/{id}")
+ public ResponseResult getTestDataWithMaster(@PathVariable Long id) {
+ return ResponseResult.success(testMasterService.getTestById(id)); // 使用主数据源查询数据
+ }
+
+ @Operation(summary = "使用从数据源查询测试数据", description = "使用从数据源查询测试数据")
+ @GetMapping("/slave/{id}")
+ public ResponseResult getTestDataWithSlave(@PathVariable Long id) {
+ return ResponseResult.success(testSlaveService.getTestById(id)); // 使用从数据源查询数据
+ }
+}
+```
+
+## 4. 使用方法
+
+### 4.1 注解方式
+使用 `@DS` 注解可以指定方法或类使用的数据源:
+
+```java
+// 类级别:整个类的方法都使用 master 数据源
+@Service
+@DS("master")
+public class TestServiceImpl {
+ // ...
+}
+
+// 方法级别:该方法使用 slave 数据源(优先级高于类级别)
+@DS("slave")
+public TestEntity getTestById(Long id) {
+ return getById(id);
+}
+```
+
+### 4.2 动态数据源名称
+支持从方法参数或上下文中获取动态数据源名称:
+
+```java
+// 从方法参数中获取数据源名称
+@DS("#datasourceName")
+public TestEntity getTestById(Long id, String datasourceName) {
+ return getById(id);
+}
+
+// 从上下文或SpEL表达式中获取数据源名称
+@DS("#{@systemConfig.getDatasourceName()}")
+public TestEntity getTestById(Long id) {
+ return getById(id);
+}
+```
+
+### 4.3 数据源优先级
+数据源的优先级顺序为:
+1. 方法上的 `@DS` 注解
+2. 类上的 `@DS` 注解
+3. 全局默认数据源(primary)
+注意:Service 层的 @DS 注解具有更高优先级
+
+## 5. 测试验证
+
+### 5.1 编译测试
+运行以下命令编译项目,确保配置正确:
+
+```bash
+cd d:\workSpace\tacit; mvn clean compile -pl tacit-admin -am
+```
+
+### 5.2 运行测试
+启动项目后,通过以下方式测试多数据源:
+
+1. **使用主数据源创建数据**:
+ ```bash
+ POST /multi-datasource/master/create
+ Content-Type: application/json
+
+ {
+ "name": "测试用户",
+ "age": 25,
+ "email": "test@example.com"
+ }
+ ```
+
+2. **使用主数据源查询数据**:
+ ```bash
+ GET /multi-datasource/master/1
+ ```
+
+3. **使用从数据源查询数据**:
+ ```bash
+ GET /multi-datasource/slave/1
+ ```
+
+## 6. 注意事项
+
+1. **依赖冲突**:确保项目中没有其他数据源相关的依赖冲突,如 `spring-boot-starter-jdbc` 或其他动态数据源框架。
+
+2. **数据源名称**:数据源名称必须与配置文件中的名称一致,大小写敏感。
+
+3. **事务管理**:多数据源环境下,事务管理需要特别注意,建议使用 `@DSTransactional` 注解替代 `@Transactional` 注解。
+
+4. **严格模式**:生产环境建议开启严格模式(`strict: true`),确保数据源名称正确。
+
+5. **性能考虑**:频繁切换数据源会带来性能开销,建议根据业务场景合理设计数据源使用策略。
+
+6. **配置中心**:如果使用配置中心(如 Nacos),可以将数据源配置迁移到配置中心,便于动态调整。
+
+## 7. 常见问题
+
+### 7.1 数据源切换不生效
+- 检查 `@DS` 注解是否正确添加到方法或类上
+- 检查数据源名称是否与配置文件一致
+- 检查是否开启了严格模式,以及默认数据源是否配置正确
+
+### 7.2 事务不生效
+- 使用 `@DSTransactional` 注解替代 `@Transactional` 注解
+- 确保事务方法是 `public` 修饰的
+- 确保事务方法不是通过内部调用的(Spring AOP 代理机制)
+
+
diff --git a/pom.xml b/pom.xml
index 62d7568..ca84e6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -134,13 +134,6 @@
${nacos-client.version}
-
-
- org.springframework.cloud
- spring-cloud-starter-bootstrap
- 4.0.4
-
-
org.springdoc
diff --git a/tacit-admin/pom.xml b/tacit-admin/pom.xml
index f9d1561..94efb23 100644
--- a/tacit-admin/pom.xml
+++ b/tacit-admin/pom.xml
@@ -41,17 +41,18 @@
com.baomidou
mybatis-plus-boot-starter
+
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+ 3.6.1
+
-
com.mysql
mysql-connector-j
- runtime
@@ -94,11 +95,6 @@
resilience4j-spring-boot3
-
-
- org.springframework.cloud
- spring-cloud-starter-bootstrap
-
diff --git a/tacit-admin/src/main/java/com/tacit/admin/controller/MethodLevelDSTestController.java b/tacit-admin/src/main/java/com/tacit/admin/controller/MethodLevelDSTestController.java
new file mode 100644
index 0000000..ea7c9f9
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/controller/MethodLevelDSTestController.java
@@ -0,0 +1,86 @@
+package com.tacit.admin.controller;
+
+import com.tacit.common.entity.ResponseResult;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.service.MethodLevelDSTestService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 方法级 @DS 注解使用样例 - 控制器
+ * 演示不同场景下的方法级数据源切换
+ */
+@RestController
+@RequestMapping("/test")
+@Tag(name = "方法级 @DS 注解测试接口", description = "用于测试方法级 @DS 注解的接口")
+public class MethodLevelDSTestController {
+
+ @Autowired
+ private MethodLevelDSTestService methodLevelDSTestService;
+
+ @Operation(summary = "示例1:保存到主数据源", description = "使用 @DS(\"master\") 指定使用主数据源")
+ @PostMapping("/save-to-master")
+ public ResponseResult saveToMaster(@RequestBody TestEntity testEntity) {
+ boolean result = methodLevelDSTestService.saveToMaster(testEntity);
+ return ResponseResult.success(result);
+ }
+
+ @Operation(summary = "示例2:从从数据源查询", description = "使用 @DS(\"slave\") 指定使用从数据源")
+ @GetMapping("/get-from-slave/{id}")
+ public ResponseResult getFromSlave(@PathVariable Long id) {
+ TestEntity result = methodLevelDSTestService.getFromSlave(id);
+ return ResponseResult.success(result);
+ }
+
+ @Operation(summary = "示例3:动态数据源名称", description = "使用 @DS(\"#datasourceName\") 从方法参数中获取数据源名称")
+ @PostMapping("/save-to-dynamic")
+ public ResponseResult saveToDynamicDatasource(@RequestBody TestEntity testEntity,
+ @RequestParam String datasourceName) {
+ boolean result = methodLevelDSTestService.saveToDynamicDatasource(testEntity, datasourceName);
+ return ResponseResult.success(result);
+ }
+
+ @Operation(summary = "示例4:结合事务使用", description = "使用 @DSTransactional 注解支持多数据源事务")
+ @PostMapping("/save-with-transaction")
+ public ResponseResult saveWithTransaction(@RequestBody TestEntity testEntity) {
+ boolean result = methodLevelDSTestService.saveWithTransaction(testEntity);
+ return ResponseResult.success(result);
+ }
+
+ @Operation(summary = "示例5-1:从主数据源查询", description = "同一个类中不同方法使用不同数据源 - 从主数据源查询")
+ @GetMapping("/get-from-master/{id}")
+ public ResponseResult getFromMaster(@PathVariable Long id) {
+ TestEntity result = methodLevelDSTestService.getFromMaster(id);
+ return ResponseResult.success(result);
+ }
+
+ @Operation(summary = "示例5-2:从从数据源查询", description = "同一个类中不同方法使用不同数据源 - 从从数据源查询")
+ @GetMapping("/get-from-slave-db/{id}")
+ public ResponseResult getFromSlaveDB(@PathVariable Long id) {
+ TestEntity result = methodLevelDSTestService.getFromSlaveDB(id);
+ return ResponseResult.success(result);
+ }
+
+ @Operation(summary = "示例6:使用默认数据源", description = "不使用 @DS 注解,使用全局默认数据源(primary)")
+ @GetMapping("/get-from-default/{id}")
+ public ResponseResult getFromDefault(@PathVariable Long id) {
+ TestEntity result = methodLevelDSTestService.getFromDefault(id);
+ return ResponseResult.success(result);
+ }
+
+
+ @Operation(summary = "示例7:获取mapper方法级数据源切换", description = "传入数据源")
+ @GetMapping("/get-one/{datasourceName}")
+ public ResponseResult getFromDefault(@PathVariable String datasourceName) {
+ TestEntity result = methodLevelDSTestService.getOneTest(datasourceName);
+ return ResponseResult.success(result);
+ }
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/controller/MultiDatasourceTestController.java b/tacit-admin/src/main/java/com/tacit/admin/controller/MultiDatasourceTestController.java
new file mode 100644
index 0000000..e7e4c5d
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/controller/MultiDatasourceTestController.java
@@ -0,0 +1,48 @@
+package com.tacit.admin.controller;
+
+import com.tacit.common.entity.ResponseResult;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.service.TestService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/test")
+@Tag(name = "多数据源测试接口", description = "用于测试多数据源的接口")
+public class MultiDatasourceTestController {
+
+ @Autowired
+ @Qualifier("testMasterService")
+ private TestService testMasterService;
+
+ @Autowired
+ @Qualifier("testSlaveService")
+ private TestService testSlaveService;
+
+ @Operation(summary = "使用主数据源创建测试数据", description = "使用主数据源创建测试数据")
+ @PostMapping("/master/create")
+ public ResponseResult createTestDataWithMaster(@RequestBody TestEntity testEntity) {
+ testMasterService.save(testEntity);
+ return ResponseResult.success(testEntity);
+ }
+
+ @Operation(summary = "使用主数据源查询测试数据", description = "使用主数据源查询测试数据")
+ @GetMapping("/master/{id}")
+ public ResponseResult getTestDataWithMaster(@PathVariable Long id) {
+ return ResponseResult.success(testMasterService.getTestById(id));
+ }
+
+ @Operation(summary = "使用从数据源查询测试数据", description = "使用从数据源查询测试数据")
+ @GetMapping("/slave/{id}")
+ public ResponseResult getTestDataWithSlave(@PathVariable Long id) {
+ return ResponseResult.success(testSlaveService.getTestById(id));
+ }
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/entity/TestEntity.java b/tacit-admin/src/main/java/com/tacit/admin/entity/TestEntity.java
new file mode 100644
index 0000000..5cfc4e1
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/entity/TestEntity.java
@@ -0,0 +1,19 @@
+package com.tacit.admin.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.tacit.common.entity.Base;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.data.annotation.Id;
+
+@Data
+@TableName("test")
+public class TestEntity{
+ @TableId(type = IdType.AUTO)
+ private Long id;
+ private String name;
+ private Integer age;
+ private String email;
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/mapper/TestMapper.java b/tacit-admin/src/main/java/com/tacit/admin/mapper/TestMapper.java
new file mode 100644
index 0000000..f0899f3
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/mapper/TestMapper.java
@@ -0,0 +1,18 @@
+package com.tacit.admin.mapper;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.tacit.admin.entity.TestEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface TestMapper extends BaseMapper {
+
+ @DS("master")
+ TestEntity getOneTestMaster();
+
+ @DS("slave")
+ TestEntity getOneTestSlave();
+
+ TestEntity getOneTest();
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/service/MethodLevelDSTestService.java b/tacit-admin/src/main/java/com/tacit/admin/service/MethodLevelDSTestService.java
new file mode 100644
index 0000000..f9ce62e
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/service/MethodLevelDSTestService.java
@@ -0,0 +1,69 @@
+package com.tacit.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.tacit.admin.entity.TestEntity;
+
+/**
+ * 方法级 @DS 注解使用样例 - Service 接口
+ * 定义方法级数据源切换的服务方法
+ */
+public interface MethodLevelDSTestService extends IService {
+
+ /**
+ * 示例1:基本的方法级数据源切换 - 保存到主数据源
+ * @param testEntity 测试实体
+ * @return 保存结果
+ */
+ boolean saveToMaster(TestEntity testEntity);
+
+ /**
+ * 示例2:基本的方法级数据源切换 - 从从数据源查询
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ TestEntity getFromSlave(Long id);
+
+ /**
+ * 示例3:动态数据源名称 - 从方法参数中获取数据源名称
+ * @param testEntity 测试实体
+ * @param datasourceName 数据源名称
+ * @return 保存结果
+ */
+ boolean saveToDynamicDatasource(TestEntity testEntity, String datasourceName);
+
+ /**
+ * 示例4:结合事务使用 - 支持多数据源事务
+ * @param testEntity 测试实体
+ * @return 保存结果
+ */
+ boolean saveWithTransaction(TestEntity testEntity);
+
+ /**
+ * 示例5:同一个类中不同方法使用不同数据源 - 从主数据源查询
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ TestEntity getFromMaster(Long id);
+
+ /**
+ * 示例5:同一个类中不同方法使用不同数据源 - 从从数据源查询
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ TestEntity getFromSlaveDB(Long id);
+
+ /**
+ * 示例6:默认数据源 - 使用全局默认数据源
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ TestEntity getFromDefault(Long id);
+
+ /**
+ * 示例7:获取mapper方法级数据源切换
+ * @param datasourceName 数据源名称
+ * @return 测试结果
+ */
+ TestEntity getOneTest(String datasourceName);
+
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/service/TestService.java b/tacit-admin/src/main/java/com/tacit/admin/service/TestService.java
new file mode 100644
index 0000000..21ebb10
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/service/TestService.java
@@ -0,0 +1,8 @@
+package com.tacit.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.tacit.admin.entity.TestEntity;
+
+public interface TestService extends IService {
+ TestEntity getTestById(Long id);
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/service/impl/MethodLevelDSTestServiceImpl.java b/tacit-admin/src/main/java/com/tacit/admin/service/impl/MethodLevelDSTestServiceImpl.java
new file mode 100644
index 0000000..8261000
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/service/impl/MethodLevelDSTestServiceImpl.java
@@ -0,0 +1,124 @@
+package com.tacit.admin.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.mapper.TestMapper;
+import com.tacit.admin.service.MethodLevelDSTestService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 方法级 @DS 注解使用样例
+ * 展示不同场景下的方法级数据源切换
+ */
+@Service
+public class MethodLevelDSTestServiceImpl extends ServiceImpl implements MethodLevelDSTestService {
+
+ /**
+ * 示例1:基本的方法级数据源切换
+ * 使用 @DS("master") 指定使用主数据源
+ * @param testEntity 测试实体
+ * @return 保存结果
+ */
+ @DS("master")
+ @Override
+ public boolean saveToMaster(TestEntity testEntity) {
+ return save(testEntity);
+ }
+
+ /**
+ * 示例2:基本的方法级数据源切换
+ * 使用 @DS("slave") 指定使用从数据源
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ @DS("slave")
+ @Override
+ public TestEntity getFromSlave(Long id) {
+ return getById(id);
+ }
+
+ /**
+ * 示例3:动态数据源名称
+ * 使用 @DS("#datasourceName") 从方法参数中获取数据源名称
+ * @param testEntity 测试实体
+ * @param datasourceName 数据源名称
+ * @return 保存结果
+ */
+ @DS("#datasourceName")
+ @Override
+ public boolean saveToDynamicDatasource(TestEntity testEntity, String datasourceName) {
+ return save(testEntity);
+ }
+
+ /**
+ * 示例4:结合事务使用
+ * 使用 @DSTransactional 注解支持多数据源事务
+ * @param testEntity 测试实体
+ * @return 保存结果
+ */
+ @DS("master")
+ @DSTransactional
+ @Override
+ public boolean saveWithTransaction(TestEntity testEntity) {
+ // 保存数据
+ boolean result = save(testEntity);
+ // 模拟业务逻辑
+ if (result) {
+ // 可以在同一个事务中操作其他数据
+ TestEntity anotherEntity = new TestEntity();
+ anotherEntity.setName("关联数据");
+ anotherEntity.setAge(30);
+ anotherEntity.setEmail("related@example.com");
+ return save(anotherEntity);
+ }
+ return false;
+ }
+
+ /**
+ * 示例5:同一个类中不同方法使用不同数据源
+ * 方法1:使用主数据源
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ @DS("master")
+ @Override
+ public TestEntity getFromMaster(Long id) {
+ return getById(id);
+ }
+
+ /**
+ * 示例5:同一个类中不同方法使用不同数据源
+ * 方法2:使用从数据源
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ @DS("slave")
+ @Override
+ public TestEntity getFromSlaveDB(Long id) {
+ return getById(id);
+ }
+
+ /**
+ * 示例6:默认数据源
+ * 不使用 @DS 注解,使用全局默认数据源(primary)
+ * @param id 主键ID
+ * @return 查询结果
+ */
+ @Override
+ public TestEntity getFromDefault(Long id) {
+ return getById(id);
+ }
+
+ @Override
+ public TestEntity getOneTest(String datasourceName) {
+ return switch (datasourceName) {
+ case "master" -> baseMapper.getOneTestMaster();
+ case "slave" -> baseMapper.getOneTestSlave();
+ default -> baseMapper.getOneTest();
+ };
+ }
+
+
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/service/impl/TestMasterServiceImpl.java b/tacit-admin/src/main/java/com/tacit/admin/service/impl/TestMasterServiceImpl.java
new file mode 100644
index 0000000..8eff180
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/service/impl/TestMasterServiceImpl.java
@@ -0,0 +1,17 @@
+package com.tacit.admin.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.mapper.TestMapper;
+import com.tacit.admin.service.TestService;
+import org.springframework.stereotype.Service;
+
+@Service("testMasterService")
+@DS("master") // 指定使用主数据源
+public class TestMasterServiceImpl extends ServiceImpl implements TestService {
+ @Override
+ public TestEntity getTestById(Long id) {
+ return getById(id);
+ }
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/java/com/tacit/admin/service/impl/TestSlaveServiceImpl.java b/tacit-admin/src/main/java/com/tacit/admin/service/impl/TestSlaveServiceImpl.java
new file mode 100644
index 0000000..803d473
--- /dev/null
+++ b/tacit-admin/src/main/java/com/tacit/admin/service/impl/TestSlaveServiceImpl.java
@@ -0,0 +1,17 @@
+package com.tacit.admin.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.tacit.admin.entity.TestEntity;
+import com.tacit.admin.mapper.TestMapper;
+import com.tacit.admin.service.TestService;
+import org.springframework.stereotype.Service;
+
+@Service("testSlaveService")
+@DS("slave") // 指定使用从数据源
+public class TestSlaveServiceImpl extends ServiceImpl implements TestService {
+ @Override
+ public TestEntity getTestById(Long id) {
+ return getById(id);
+ }
+}
\ No newline at end of file
diff --git a/tacit-admin/src/main/resources/application-dev.yml b/tacit-admin/src/main/resources/application-dev.yml
index 67ff5c7..84e841b 100644
--- a/tacit-admin/src/main/resources/application-dev.yml
+++ b/tacit-admin/src/main/resources/application-dev.yml
@@ -1,3 +1,16 @@
-server:
- port: 8082
-
+spring:
+ config:
+ import: "optional:nacos:${spring.application.name}.yaml"
+ cloud:
+ nacos:
+ discovery:
+ server-addr: 117.72.94.232:9091
+ username: nacos
+ password: nacos
+ namespace: dev
+ config:
+ server-addr: 117.72.94.232:9091
+ file-extension: yaml
+ username: nacos
+ password: nacos
+ namespace: dev
\ No newline at end of file
diff --git a/tacit-admin/src/main/resources/application-qa.yml b/tacit-admin/src/main/resources/application-qa.yml
index 67ff5c7..90606d1 100644
--- a/tacit-admin/src/main/resources/application-qa.yml
+++ b/tacit-admin/src/main/resources/application-qa.yml
@@ -1,3 +1,16 @@
-server:
- port: 8082
-
+spring:
+ config:
+ import: "optional:nacos:${spring.application.name}.yaml"
+ cloud:
+ nacos:
+ discovery:
+ server-addr: 117.72.94.232:9091
+ username: nacos
+ password: nacos
+ namespace: ${nacos.namespace}
+ config:
+ server-addr: 117.72.94.232:9091
+ file-extension: yaml
+ username: nacos
+ password: nacos
+ namespace: ${nacos.namespace}
\ No newline at end of file
diff --git a/tacit-admin/src/main/resources/application.yml b/tacit-admin/src/main/resources/application.yml
index 3d7808a..6cf9270 100644
--- a/tacit-admin/src/main/resources/application.yml
+++ b/tacit-admin/src/main/resources/application.yml
@@ -1,3 +1,5 @@
spring:
+ application:
+ name: tacit-admin
profiles:
active: dev
diff --git a/tacit-admin/src/main/resources/bootstrap.yml b/tacit-admin/src/main/resources/bootstrap.yml
deleted file mode 100644
index eb7e6dd..0000000
--- a/tacit-admin/src/main/resources/bootstrap.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-spring:
- application:
- name: tacit-admin
- config:
- import: "optional:nacos:${spring.application.name}.yaml"
- cloud:
- nacos:
- discovery:
- server-addr: ${nacos.server-addr:117.72.94.232:9091}
- username: ${nacos.username:nacos}
- password: ${nacos.password:nacos}
- namespace: ${nacos.namespace:33140c53-3f57-4bd2-b9c8-f507581b6ca2}
- config:
- server-addr: ${nacos.server-addr:117.72.94.232:9091}
- file-extension: yaml
- username: ${nacos.username:nacos}
- password: ${nacos.password:nacos}
- namespace: ${nacos.namespace:33140c53-3f57-4bd2-b9c8-f507581b6ca2}
\ No newline at end of file
diff --git a/tacit-admin/src/main/resources/mapper/TestMapper.xml b/tacit-admin/src/main/resources/mapper/TestMapper.xml
new file mode 100644
index 0000000..d229fe2
--- /dev/null
+++ b/tacit-admin/src/main/resources/mapper/TestMapper.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tacit-admin/src/main/resources/tacit-admin.yaml b/tacit-admin/src/main/resources/tacit-admin.yaml
deleted file mode 100644
index 8437fe6..0000000
--- a/tacit-admin/src/main/resources/tacit-admin.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-server:
- port: 8082
-
-spring:
- datasource:
- driver-class-name: com.oceanbase.jdbc.Driver
- url: jdbc:oceanbase://localhost:2881/tacit?useUnicode=true&characterEncoding=utf-8&useSSL=false
- username: root
- password: password
-
-mybatis-plus:
- configuration:
- map-underscore-to-camel-case: true
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- mapper-locations: classpath*:mapper/**/*.xml
- type-aliases-package: com.tacit.admin.entity
-
-# Swagger Configuration
-springdoc:
- api-docs:
- enabled: true
- path: /v3/api-docs
- swagger-ui:
- enabled: true
- path: /swagger-ui.html
-
-# Logging Configuration
-logging:
- level:
- com.tacit.admin: debug
diff --git a/tacit-app-api/pom.xml b/tacit-app-api/pom.xml
index bca7f57..2d5265c 100644
--- a/tacit-app-api/pom.xml
+++ b/tacit-app-api/pom.xml
@@ -86,11 +86,6 @@
test
-
-
- org.springframework.cloud
- spring-cloud-starter-bootstrap
-
com.tacit
common-redis
diff --git a/tacit-app-api/src/main/resources/application-dev.yml b/tacit-app-api/src/main/resources/application-dev.yml
index ac79bd8..a5632f7 100644
--- a/tacit-app-api/src/main/resources/application-dev.yml
+++ b/tacit-app-api/src/main/resources/application-dev.yml
@@ -1,3 +1,17 @@
-server:
- port: 8083
+spring:
+ config:
+ import: "optional:nacos:${spring.application.name}.yaml"
+ cloud:
+ nacos:
+ discovery:
+ server-addr: 117.72.94.232:9091
+ username: nacos
+ password: nacos
+ namespace: dev
+ config:
+ server-addr: 117.72.94.232:9091
+ file-extension: yaml
+ username: nacos
+ password: nacos
+ namespace: dev
diff --git a/tacit-app-api/src/main/resources/application-qa.yml b/tacit-app-api/src/main/resources/application-qa.yml
index ac79bd8..ff87a27 100644
--- a/tacit-app-api/src/main/resources/application-qa.yml
+++ b/tacit-app-api/src/main/resources/application-qa.yml
@@ -1,3 +1,17 @@
-server:
- port: 8083
+spring:
+ config:
+ import: "optional:nacos:${spring.application.name}.yaml"
+ cloud:
+ nacos:
+ discovery:
+ server-addr: 117.72.94.232:9091
+ username: nacos
+ password: nacos
+ namespace: ${nacos.namespace}
+ config:
+ server-addr: 117.72.94.232:9091
+ file-extension: yaml
+ username: nacos
+ password: nacos
+ namespace: ${nacos.namespace}
diff --git a/tacit-app-api/src/main/resources/application.yml b/tacit-app-api/src/main/resources/application.yml
index 3d7808a..6b98902 100644
--- a/tacit-app-api/src/main/resources/application.yml
+++ b/tacit-app-api/src/main/resources/application.yml
@@ -1,3 +1,5 @@
spring:
+ application:
+ name: tacit-app-api
profiles:
active: dev
diff --git a/tacit-app-api/src/main/resources/bootstrap.yml b/tacit-app-api/src/main/resources/bootstrap.yml
deleted file mode 100644
index 59221dd..0000000
--- a/tacit-app-api/src/main/resources/bootstrap.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-spring:
- application:
- name: tacit-app-api
- config:
- import: "optional:nacos:${spring.application.name}.yaml"
- cloud:
- nacos:
- discovery:
- server-addr: ${nacos.server-addr:117.72.94.232:9091}
- username: ${nacos.username:nacos}
- password: ${nacos.password:nacos}
- namespace: ${nacos.namespace:33140c53-3f57-4bd2-b9c8-f507581b6ca2}
- config:
- server-addr: ${nacos.server-addr:117.72.94.232:9091}
- file-extension: yaml
- username: ${nacos.username:nacos}
- password: ${nacos.password:nacos}
- namespace: ${nacos.namespace:33140c53-3f57-4bd2-b9c8-f507581b6ca2}
diff --git a/tacit-gateway/pom.xml b/tacit-gateway/pom.xml
index 99961ea..a4ea2ef 100644
--- a/tacit-gateway/pom.xml
+++ b/tacit-gateway/pom.xml
@@ -51,12 +51,6 @@
-
-
- org.springframework.cloud
- spring-cloud-starter-bootstrap
-
-
com.alibaba.cloud
diff --git a/tacit-gateway/src/main/resources/application-dev.yml b/tacit-gateway/src/main/resources/application-dev.yml
index 11e54c5..84e841b 100644
--- a/tacit-gateway/src/main/resources/application-dev.yml
+++ b/tacit-gateway/src/main/resources/application-dev.yml
@@ -1,2 +1,16 @@
-server:
- port: 8081
+spring:
+ config:
+ import: "optional:nacos:${spring.application.name}.yaml"
+ cloud:
+ nacos:
+ discovery:
+ server-addr: 117.72.94.232:9091
+ username: nacos
+ password: nacos
+ namespace: dev
+ config:
+ server-addr: 117.72.94.232:9091
+ file-extension: yaml
+ username: nacos
+ password: nacos
+ namespace: dev
\ No newline at end of file
diff --git a/tacit-gateway/src/main/resources/application-qa.yml b/tacit-gateway/src/main/resources/application-qa.yml
index 11e54c5..2ccfda6 100644
--- a/tacit-gateway/src/main/resources/application-qa.yml
+++ b/tacit-gateway/src/main/resources/application-qa.yml
@@ -1,2 +1,16 @@
-server:
- port: 8081
+spring:
+ config:
+ import: "optional:nacos:${spring.application.name}.yaml"
+ cloud:
+ nacos:
+ discovery:
+ server-addr: 117.72.94.232:9091
+ username: nacos
+ password: nacos
+ namespace: ${nacos.namespace}
+ config:
+ server-addr: 117.72.94.232:9091
+ file-extension: yaml
+ username: nacos
+ password: nacos
+ namespace: ${nacos.namespace}
diff --git a/tacit-gateway/src/main/resources/application.yml b/tacit-gateway/src/main/resources/application.yml
index 3d7808a..a990477 100644
--- a/tacit-gateway/src/main/resources/application.yml
+++ b/tacit-gateway/src/main/resources/application.yml
@@ -1,3 +1,7 @@
spring:
+ application:
+ name: tacit-gateway
+ main:
+ web-application-type: reactive
profiles:
active: dev
diff --git a/tacit-gateway/src/main/resources/bootstrap.yml b/tacit-gateway/src/main/resources/bootstrap.yml
deleted file mode 100644
index ce0d220..0000000
--- a/tacit-gateway/src/main/resources/bootstrap.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-spring:
- application:
- name: tacit-gateway
- config:
- import: "optional:nacos:${spring.application.name}.yaml"
- main:
- web-application-type: reactive
- cloud:
- nacos:
- discovery:
- server-addr: ${nacos.server-addr:117.72.94.232:9091}
- username: ${nacos.username:nacos}
- password: ${nacos.password:nacos}
- namespace: ${nacos.namespace:33140c53-3f57-4bd2-b9c8-f507581b6ca2}
- config:
- server-addr: ${nacos.server-addr:117.72.94.232:9091}
- file-extension: yaml
- username: ${nacos.username:nacos}
- password: ${nacos.password:nacos}
- namespace: ${nacos.namespace:33140c53-3f57-4bd2-b9c8-f507581b6ca2}
-