我有一个数据库qazxsw poi,其数据库链接到其他数据库:qazxsw poi,MAIN_DB
,EMP_DB1
,EMP_DB2
。为简单起见,让我们假设另外两个数据库。
EMP_DB3
和EMP_DBx
都有表EMP_DB1
具有相同的表结构:
EMP_DB2
EMPLOYEE
能够通过他们的create table employee(
id number primary key,
first_name varchar2(40),
last_name varchar2(40));
查询MAIN_DB
和EMP_DB1
:
EMP_DB2
我想让我的dblink
听取select * from employee@emp_db1;
1 John Smith
select * from employee@emp_db2;
2 Jane Doe
并根据RestController
查询相应的/employee/{id}
。
当前工作(不理想)的例子:
com.apitest.repository.PersonRepository
EMP_DBx
com.apitest.repository.EmployeeRepository
id
com.apitest.repository.Employee2Repository
package com.apitest.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
@NoRepositoryBean
interface PersonRepository<T> extends JpaRepository<T, Long> {
}
com.apitest.model.Person
package com.apitest.repository;
import com.apitest.model.Employee;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends PersonRepository<Employee> {
Employee findById(Long id);
}
com.apitest.model.Employee
package com.apitest.repository;
import com.apitest.model.Employee2;
import org.springframework.stereotype.Repository;
@Repository
public interface Employee2Repository extends PersonRepository<Employee2> {
Employee2 findById(Long id);
}
com.apitest.model.Employee2
package com.apitest.model;
...
@MappedSuperclass
public abstract class Person {
private long id;
private String firstName;
private String lastName;
@Id
@Column(name = "ID")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Basic
@Column(name = "FIRST_NAME")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Basic
@Column(name = "LAST_NAME")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String toString() {
return "id: " + id + ", " +
"first_name: " + firstName + ", " +
"last_name: " + lastName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person employee = (Person) o;
return id == employee.id &&
Objects.equals(firstName, employee.firstName) &&
Objects.equals(lastName, employee.lastName);
}
@Override
public int hashCode() {
return Objects.hash(id, firstName, lastName);
}
}
com.apitest.controller.EmployeeController
package com.apitest.model;
import javax.persistence.Entity;
@Entity(name = "EMPLOYEE@EMP_DB1")
public class Employee extends Person {
}
有没有办法参数化package com.apitest.model;
import javax.persistence.Entity;
@Entity(name = "EMPLOYEE@EMP_DB2")
public class Employee2 extends Person {
}
名称?
package com.apitest.controller;
...
@RestController
@RequestMapping("/employee")
public class EmployeeController {
private final EmployeeRepository employeeRepository;
private final Employee2Repository employee2Repository;
@Autowired
public EmployeeController(EmployeeRepository employeeRepository, Employee2Repository employee2Repository) {
this.employeeRepository = employeeRepository;
this.employee2Repository = employee2Repository;
}
// logic will be different, this is just an example
@RequestMapping(path = "/{id}", method = RequestMethod.GET)
public ResponseEntity<?> getByUserid(@PathVariable("id") Long id) {
if (id % 2 == 1) {
Employee employee = employeeRepository.findById(id);
return new ResponseEntity<>(ResponseEntity.ok(employee), HttpStatus.OK);
}
else {
Employee2 employee2 = employee2Repository.findById(id);
return new ResponseEntity<>(ResponseEntity.ok(employee2), HttpStatus.OK);
}
}
}
如果没有,我怎么能用Entity
查询dblink?
EmployeeRepository:
@Entity(name = "EMPLOYEE@{db_link_name}")
public class Employee extends Person
Spring不喜欢查询字符串中的@Query
。我能够创建同义词以解决这个问题,但我无法参数化同义词名称:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Query("select e from employee@emp_dbx e e.id = ?1")
Employee findById(Long id);
}
期望的行为:
@dblink_name
我的问题归结为什么是最好的设计完全完成Spring,我怎样才能做到这一点?
您应该实现多租户架构。这将是用于您的用例的正确设计模式。查看此链接,使您的spring / spring-boot应用程序成为多租户。 create or replace synonym employee_emp_db1 for employee@emp_db1;
create or replace synonym employee_emp_db2 for employee@emp_db2;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Query("select e from ?1 e e.id = ?2")
Employee findById(String dblinkName, Long id);
}
QuerySyntaxException: unexpected token: ? near line 1, column 15 [select e from ?1 e e.id = ?2]