如何在Spring Boot中配置Cassandra与MySQL实现按请求参数切换数据源
1. 引入必要依赖
在项目的pom.xml中加入两个数据库对应的starter依赖:
<!-- MySQL 相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <!-- Cassandra 相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-cassandra</artifactId> </dependency>
2. 编写数据源配置
在application.yml中分别配置两个数据库的连接参数,避免前缀冲突:
# MySQL 配置 spring: datasource: mysql: jdbc-url: jdbc:mysql://localhost:3306/你的库名?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 username: root password: 你的MySQL密码 driver-class-name: com.mysql.cj.jdbc.Driver jpa: mysql: hibernate: ddl-auto: update show-sql: true properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect # Cassandra 配置 data: cassandra: contact-points: 127.0.0.1 port: 9042 keyspace-name: 你的Cassandra keyspace名称 username: cassandra password: 你的Cassandra密码 local-datacenter: datacenter1 schema-action: CREATE_IF_NOT_EXISTS
3. 编写MySQL数据源配置类
通过配置类单独扫描MySQL对应的实体和Repository包,添加@Primary注解标记MySQL为默认数据源避免冲突:
@Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = "com.xxx.demo.mysql.repository", // 替换为你的MySQL Repository包路径 entityManagerFactoryRef = "mysqlEntityManagerFactory", transactionManagerRef = "mysqlTransactionManager" ) public class MysqlDataSourceConfig { @Bean @Primary @ConfigurationProperties(prefix = "spring.datasource.mysql") public DataSource mysqlDataSource() { return DataSourceBuilder.create().build(); } @Bean @Primary public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory( EntityManagerFactoryBuilder builder) { return builder .dataSource(mysqlDataSource()) .packages("com.xxx.demo.mysql.entity") // 替换为你的MySQL实体类包路径 .persistenceUnit("mysqlPersistenceUnit") .properties(Map.of("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect", "hibernate.hbm2ddl.auto", "update", "show-sql", true)) .build(); } @Bean @Primary public PlatformTransactionManager mysqlTransactionManager( @Qualifier("mysqlEntityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } }
4. 编写Cassandra数据源配置类
单独配置Cassandra的连接属性和扫描路径:
@Configuration @EnableCassandraRepositories(basePackages = "com.xxx.demo.cassandra.repository") // 替换为你的Cassandra Repository包路径 public class CassandraConfig extends AbstractCassandraConfiguration { @Value("${spring.data.cassandra.keyspace-name}") private String keyspaceName; @Value("${spring.data.cassandra.contact-points}") private String contactPoints; @Value("${spring.data.cassandra.port}") private int port; @Value("${spring.data.cassandra.local-datacenter}") private String localDatacenter; @Value("${spring.data.cassandra.username}") private String username; @Value("${spring.data.cassandra.password}") private String password; @Override protected String getKeyspaceName() { return keyspaceName; } @Override protected String getContactPoints() { return contactPoints; } @Override protected int getPort() { return port; } @Override protected String getLocalDataCenter() { return localDatacenter; } @Override protected CqlSessionFactoryBean session() { CqlSessionFactoryBean session = super.session(); session.setUsername(username); session.setPassword(password); return session; } @Override protected String[] getEntityBasePackages() { return new String[]{"com.xxx.demo.cassandra.entity"}; // 替换为你的Cassandra实体类包路径 } @Override protected SchemaAction getSchemaAction() { return SchemaAction.CREATE_IF_NOT_EXISTS; } }
5. 分层存放代码
按包路径区分两个数据库的相关代码,避免扫描冲突:
- MySQL实体类存放在
com.xxx.demo.mysql.entity包,Repository接口存放在com.xxx.demo.mysql.repository包,示例如下:
@Repository public interface MysqlRepository extends JpaRepository<你的MySQL实体类, Integer> { }
- Cassandra实体类存放在
com.xxx.demo.cassandra.entity包,Repository接口存放在com.xxx.demo.cassandra.repository包,示例如下:
@Repository public interface CassandraRepository extends CassandraRepository<你的Cassandra实体类, Integer> { }
6. 修正原有接口代码
原代码存在路径未加占位符、字符串比较用==、类型不匹配三个问题,修正后如下:
@RestController public class DataController { @Autowired private MysqlRepository sqlRepository; @Autowired private CassandraRepository cassandraRepository; @PostMapping(value = "/data/{type}") public Object getDataByDB(@PathVariable("type") String type) { int id = 123; if("Cassandra".equals(type)) { return cassandraRepository.findById(id).orElse(null); } else if("MySQL".equals(type)) { return sqlRepository.findById(id).orElse(null); } return "不支持的数据库类型"; } }
内容的提问来源于stack exchange,提问作者Susmitha
相关产品推荐
相关产品推荐

