【发布时间】:2020-03-16 12:35:06
【问题描述】:
我有一个不重要的问题:
我的情况:
- 使用 Spring Data JDBC
- 使用两个数据库
-
CrudRepository的用法
您可以在 Spring Data JDBC 中看到here,您可以通过extends CrudRepository 使用 Spring 开箱即用所有 Crud 操作 - 无需显式实现!
这是一个简单的 4 步过程:
- 定义您的属性
- 定义您的实体
- 定义一个扩展 CrudRepository 的接口和
- 使用该界面
但在使用两个数据库的情况下,有一个 5. 步骤,您必须在其中定义一个@Configuration 类。
我做了以下 5 个步骤:
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 类(每个 DB 一个)
- 你也可以在一门课上两门课,但我是这样做的:
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。
导致错误:[...]: Unknown table name:TEACHER。
有谁知道我可以如何配置 TeacherRepository 使用 DB2 作为数据源?
#回答前请注意:
这里我使用的是 Spring Data JDBC 而不是 Spring Data JPA。我知道它可以在 Spring Data JPA 中工作,就像这里描述的 https://www.baeldung.com/spring-data-jpa-multiple-databases 一样。我也知道我可以使用这些JdbcTemplate。但是那样的话,我必须自己编写这些 CRUD 操作,描述为 here,这不是我们需要的。
答案当然很好。
感谢您的帮助。
【问题讨论】:
-
spring 数据文档解释了如何使用多个数据源。你试过关注他们吗?
-
当然可以。您可以在上面的示例中看到这一点。但是你可以想象,如果我使用
StudentRepsository或TecherRepository方法(如save(),或delete(),...)spring 查询数据库,但错误的,因为我没有告诉spring 哪个存储库用于哪个数据库。这是一个配置问题。我不知道如何配置它。在 Spring JPA 中是否如您所见here 如此简单 -
根据 Crig 的说法,上面的解决方案确实对我不起作用。帖子中提供的链接在 2021 年 1 月发布了解决方案 github.com/spring-projects/spring-data-jdbc/issues/…
标签: spring spring-boot spring-data-jdbc