我有一个比较棘手的问题:
我的情况是:
- 使用 Spring Data JDBC
- 使用两个数据库
- 使用
CrudRepository
正如在这里所看到的那样,在 Spring Data JDBC 中,您可以扩展 CrudRepository
并通过 Spring 轻松地获得所有的 Crud 操作 - 无需显式实现!
这是一个简单的4步流程:
- 定义您的属性
- 定义您的实体
- 定义扩展了 CrudRepository 的接口,并且
- 利用该接口进行操作
但是,在使用两个数据库的情况下,第五步需要定义一个 @Configuration
类。
我按照以下五个步骤进行操作:
0. Pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
1. 定义您的属性
application.properties
## D1
datasource.db1.driverClassName=...
datasource.db1.username=...
datasource.db1.password=...
datasource.db1.jdbcUrl=...
## D2
datasource.db2.driverClassName=...
datasource.db2.username=...
datasource.db2.password=...
datasource.db2.jdbcUrl=...
2. 定义您的实体 (每个数据库一个实体)
Student.java // 用于 db1 数据库
@Table("STUDENT_TABLE")
public class Student{
@Id
@Column("MAT_NR")
private BigDecimal matNr;
@Column("NAME")
private String name;
}
Teacher.java // 用于db2数据库
@Table("TEACHER_TABLE")
public class Teacher{
@Id
@Column("EMPLOYEE_NR")
private BigDecimal employeeNr;
@Column("NAME")
private String name;
}
3. 定义您的存储库(每个数据库一个)
StudentRepository.java // 用于 DB1
@Repository
public interface StudentRepository extends CrudRepository<Student, BigDecimal> {}
TeacherRepository.java // 用于 DB2 数据库
@Repository
public interface TeacherRepository extends CrudRepository<Teacher, BigDecimal> {}
4. 定义你的@Configuration类(每个数据库都需要一个)
- 你也可以将两个放在同一个类中,但我是按照以下方式进行的:
Db1Config.java
@Configuration
public class Db1Config {
@Primary
@Bean("db1DataSource")
@ConfigurationProperties("datasource.db1")
public DataSource db1DataSource() {
return DataSourceBuilder.create().build();
}
}
Db2Config.java
@Configuration
public class Db2Config {
@Bean("db2DataSource")
@ConfigurationProperties("datasource.db2")
public DataSource db2DataSource() {
return DataSourceBuilder.create().build();
}
}
5. 利用接口仓库
Application.java
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired @Qualifier("studentRepository") StudentRepository studentRepository
@Autowired @Qualifier("teacherRepository") TeacherRepository teacherRepository
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
studentRepository.findById(30688).ifPresent(System.out::println); // DB1
teacherRepository.findById(5).ifPresent(System.out::println); // DB2
}
}
这部分工作正常运行!
问题在于,TeacherRepository
不查询 DB2,而是查询 DB1。
这导致出现错误:[...]: 未知表名:TEACHER
。
有人知道如何配置 TeacherRepository 使用 DB2 作为数据源吗?
# 请注意回答之前:
这里我正在使用 Spring Data JDBC 而不是 Spring Data JPA。我知道在 Spring Data JPA 中可以像这里描述的那样工作 https://www.baeldung.com/spring-data-jpa-multiple-databases。我也知道我可以使用这些 JdbcTemplate
。但是以这种方式,我必须自己编写这些 CRUD 操作,如此处所述 here,这不是我需要的。
当然,一个答案会很好。
感谢您的帮助。
StudentRepository
或TecherRepository
方法(如save()
或delete()
等),Spring会查询一个错误的数据库,因为我没有告诉Spring哪个仓库是哪个数据库的。这是一个配置问题。我不知道如何配置它。在Spring JPA中,就像你在这里看到的那样,它非常容易。 - user182410