【毕业设计】01-多数据源适配

9 阅读1分钟

目的:Spring的application.yaml中配置多种数据源,可能是MySQL或MongoDB,并根据选择的数据库使用Spring Data JDBC或Spring Data MongoDB。

思路:

  • 通过条件化配置动态加载数据源以及数据库操作工具
  • 在数据库访问层定义通用接口,为不同数据库的访问定义接口实现
  • service层统一调用
1.application.yaml配置
# 激活的数据库类型 (mysql/mongodb)
active-db: mysql

# MySQL 配置(JDBC 数据源)
spring:
  datasource:
    mysql:
      url: jdbc:mysql://127.0.0.1:3306/assemble?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
      username: root
      password: 1234
      driver-class-name: com.mysql.cj.jdbc.Driver

# MongoDB 配置
spring:
  data:
    mongodb:
      host: 
      port: 27017
      database: assemble
      username: wryyyyy
      password: 123
2.数据源配置类

MySQL:

@Configuration
@ConditionalOnProperty(name = "active-db", havingValue = "mysql")
public class MySQLConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

MongoDB:

@Configuration
@ConditionalOnProperty(name = "active-db", havingValue = "mongodb")
public class MongoDBConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.data.mongodb")
    public MongoClient mongoClient() {
        return MongoClients.create("mongodb://"
            + spring.data.mongodb.username + ":" 
            + spring.data.mongodb.password + "@"
            + spring.data.mongodb.host + ":" 
            + spring.data.mongodb.port + "/"
            + spring.data.mongodb.database);
    }

    @Bean
    public MongoTemplate mongoTemplate(MongoDatabaseFactory dbFactory) {
        return new MongoTemplate(dbFactory);
    }
}
3.数据访问层

(1)使用通用接口:

public interface GenericRepository<T, ID> {
    T save(T entity);
    Optional<T> findById(ID id);
    void deleteById(ID id);
}

(2)自定义实现

MySQL:

@Repository
@ConditionalOnProperty(name = "active-db", havingValue = "mysql")
public class MySQLUserRepository implements GenericRepository<Model, Long> {

    private final JdbcTemplate jdbcTemplate;

    public MySQLModelRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public User save(Model model) {
        //
    }
}

MongoDB:

@Repository
@ConditionalOnProperty(name = "active-db", havingValue = "mongodb")
public class MongoDBModelRepository implements GenericRepository<Model, String> {

    private final MongoTemplate mongoTemplate;

    public MongoDBModelRepository(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public User save(User user) {
        return mongoTemplate.save(user);
    }
}
4.service层统一调用
@Service
public class ModelService {
    private final GenericRepository<Model, ?> modelRepository;
    
    public ModelService(
        @Autowired(required = false) MySQLModelRepository mysqlRepo,
        @Autowired(required = false) MongoDBModelRepository mongoRepo
    ) {
        if (mysqlRepo != null) {
            this.modelRepository = mysqlRepo;
        } else if (mongoRepo != null) {
            this.modelRepository = mongoRepo;
        } else {
            throw new IllegalStateException("No active database configured!");
        }
    }

    public Model saveModel(Model model) {
        return userRepository.save(model);
    }
}