# 数据库架构设计说明 ## 概述 zsElectric-OpenApi 开放平台采用**双数据库架构**,将开放平台数据和业务系统数据进行物理隔离,同时通过动态数据源实现跨数据库访问。 ## 数据库设计 ### 1. 开放平台独立数据库 (zs_electric_openapi) 这是开放平台专用的数据库,存储以下数据: - **应用管理数据**: 第三方应用信息(AppId、AppSecret、权限等) - **API调用日志**: 所有第三方API调用记录 - **访问控制数据**: IP白名单、调用频率限制等 **优点**: - 数据隔离,互不影响 - 独立备份和恢复 - 便于权限管控 - 性能优化 ### 2. 业务系统数据库 (zs_electric) 这是原有的业务系统数据库,开放平台通过动态数据源**只读访问**该数据库: - 充电站信息 - 充电订单数据 - 用户数据 - 其他业务数据 **访问方式**: - 只读访问,确保业务系统数据安全 - 通过 `@DS("business")` 注解指定数据源 - 使用独立的Service层封装业务数据访问 ## 数据源配置 ### 开发环境 (application-dev.yml) ```yaml spring: datasource: dynamic: primary: openapi # 默认使用开放平台数据库 strict: false datasource: # 开放平台独立数据库 openapi: url: jdbc:mysql://localhost:3306/zs_electric_openapi username: root password: root # 业务系统数据库(只读) business: url: jdbc:mysql://localhost:3306/zs_electric username: root password: root ``` ### 生产环境 (application-prod.yml) ```yaml spring: datasource: dynamic: primary: openapi datasource: openapi: url: jdbc:mysql://prod-db-host:3306/zs_electric_openapi username: openapi_user # 专用账号,仅拥有openapi数据库权限 password: xxxxx business: url: jdbc:mysql://prod-db-host:3306/zs_electric username: business_readonly_user # 只读账号 password: xxxxx ``` ## 数据源使用方式 ### 1. 使用默认数据源(openapi) 对于开放平台自己的实体类(如AppInfo、ApiLog),不需要任何注解: ```java @Data @TableName("openapi_app_info") public class AppInfo { // 使用默认数据源(openapi) } @Mapper public interface AppInfoMapper extends BaseMapper { // 使用默认数据源(openapi) } @Service public class AppInfoService extends ServiceImpl { // 使用默认数据源(openapi) } ``` ### 2. 使用业务数据库(business) 对于需要访问业务系统数据的实体类,使用 `@DS("business")` 注解: ```java @Data @TableName("charging_station") public class ChargingStation { // 实体类定义 } @Mapper @DS("business") // 指定使用业务数据库 public interface ChargingStationMapper extends BaseMapper { } @Service @DS("business") // Service层也指定 public class ChargingStationService extends ServiceImpl { public List getActiveStations() { // 查询业务数据库 return lambdaQuery() .eq(ChargingStation::getStatus, 1) .list(); } } ``` ### 3. Controller层调用 Controller层直接调用对应的Service即可,数据源切换由Service层的注解控制: ```java @RestController @RequestMapping("/api/v1/charging") @RequiredArgsConstructor public class ChargingController { private final ChargingStationService chargingStationService; // 使用business数据源 private final ApiLogMapper apiLogMapper; // 使用openapi数据源 @GetMapping("/stations") public Result> getStationList() { // 调用业务系统数据 List stations = chargingStationService.getActiveStations(); // 记录到开放平台数据库 ApiLog apiLog = new ApiLog(); // ... 设置日志信息 apiLogMapper.insert(apiLog); return Result.success(stations); } } ``` ## 代码结构 ``` com.zsElectric.openapi/ ├── entity/ # 开放平台实体(使用openapi数据源) │ ├── AppInfo.java │ └── ApiLog.java ├── mapper/ # 开放平台Mapper(使用openapi数据源) │ ├── AppInfoMapper.java │ └── ApiLogMapper.java ├── business/ # 业务系统相关(使用business数据源) │ ├── entity/ │ │ ├── ChargingStation.java │ │ └── ChargingOrder.java │ ├── mapper/ │ │ ├── ChargingStationMapper.java │ │ └── ChargingOrderMapper.java │ └── service/ │ ├── ChargingStationService.java │ └── ChargingOrderService.java └── controller/ # 控制器 ├── ChargingController.java └── OrderController.java ``` ## 数据安全 ### 1. 权限控制 生产环境应为不同的数据库创建专门的账号: ```sql -- 开放平台数据库账号 CREATE USER 'openapi_user'@'%' IDENTIFIED BY 'password'; GRANT SELECT, INSERT, UPDATE, DELETE ON zs_electric_openapi.* TO 'openapi_user'@'%'; -- 业务系统只读账号 CREATE USER 'business_readonly_user'@'%' IDENTIFIED BY 'password'; GRANT SELECT ON zs_electric.* TO 'business_readonly_user'@'%'; ``` ### 2. 访问限制 - 开放平台只能**只读访问**业务数据库 - 不允许开放平台修改业务系统数据 - 所有的写操作都在开放平台自己的数据库中 ### 3. 监控审计 - 所有API调用都记录日志 - 可以追踪每个应用的访问记录 - 异常访问及时发现和处理 ## 优势总结 1. **数据隔离**: 开放平台和业务系统完全解耦 2. **安全性高**: 业务系统数据不会被第三方误操作 3. **可维护性强**: 便于独立升级和维护 4. **性能优化**: 可以针对不同的数据库进行优化 5. **灵活扩展**: 未来可以轻松添加更多数据源 ## 常见问题 ### Q1: 为什么不直接使用业务数据库? A: 考虑到安全性、性能和可维护性,开放平台应该有独立的数据库,同时通过动态数据源访问业务数据。 ### Q2: 开放平台能否写业务数据库? A: 不能。生产环境应该使用只读账号访问业务数据库,所有写操作都在开放平台自己的数据库中。 ### Q3: 如何在同一个方法中使用多个数据源? A: 不能在同一个方法中直接切换数据源。需要将不同数据源的操作拆分到不同的Service中。 ### Q4: 性能如何? A: 动态数据源切换的性能损耗非常小,可以忽略不计。通过连接池管理,可以保证高性能。 ### Q5: 如何处理事务? A: 如果需要跨数据源事务,建议使用分布式事务方案,如Seata。但对于开放平台场景,通常不需要跨数据源事务。