여러 데이터베이스에서 같은 개체를 모델링. 단순화를 위해 두 개의 다른 데이터베이스를 가정 해 봅시다.봄 부팅 : <code>EMP_DB1</code>, <code>EMP_DB2</code>, <code>EMP_DB3</code>, <code>EMP_DBx</code> : 나는 다른 데이터베이스에 dblinks을 가지고 하나의 데이터베이스 <code>MAIN_DB</code>가 DBLINK
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 [email protected]_db1;
1 John Smith
select * from [email protected]_db2;
2 Jane Doe
내 RestController
에 대한 싶습니다 /employee/{id}
에서 수신하고 해당하는을 쿼리하십시오.은 id
에 따라 다릅니다.
현재 작업 (이상시) 예 :
com.apitest.repository.PersonRepository
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.repository.EmployeeRepository
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.repository.Employee2Repository
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.Person
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.model.Employee
package com.apitest.model;
import javax.persistence.Entity;
@Entity(name = "[email protected]_DB1")
public class Employee extends Person {
}
닷컴. apitest.model.Employee2
package com.apitest.model;
import javax.persistence.Entity;
@Entity(name = "[email protected]_DB2")
public class Employee2 extends Person {
}
com.apitest.controller.EmployeeController
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
이름을 매개 변수화하는 방법이 있나요?
@Entity(name = "[email protected]{db_link_name}")
public class Employee extends Person
그렇지 않은 경우 어떻게하면 @Query
으로 dblink를 쿼리 할 수 있습니까?
EmployeeRepository :
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Query("select e from [email protected]_dbx e e.id = ?1")
Employee findById(Long id);
}
봄 쿼리 문자열에 @dblink_name
을 좋아하지 않는다.나는이 해결하기 위해 동의어를 만들 수 있어요,하지만 난 동의어 이름 매개 변수화 드릴 수 없습니다 :
create or replace synonym employee_emp_db1 for [email protected]_db1;
create or replace synonym employee_emp_db2 for [email protected]_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]
원하는 동작을 :
GET /employee/1
{
"headers": {},
"body": {
"id": 1,
"firstName": "John",
"lastName": "Smith"
},
"statusCode": "OK",
"statusCodeValue": 200
}
GET /employee/2
{
"headers": {},
"body": {
"id": 2,
"firstName": "Jane",
"lastName": "Doe"
},
"statusCode": "OK",
"statusCodeValue": 200
}
내 질문은 무엇으로 귀결 봄 - 완전히 완료 한 최고의 디자인과 어떻게 이것을 할 수 있습니까?
나는 이것이 너무 광범위하고 의견이 모호한 경계에 있다고 생각합니다. [mcve]와 코드 입력을 최소화하는 방법을 고려해보십시오. – GhostCat
@GhostCat 완전성을 위해 노력한 여러 가지를 추가했지만 너무 광범위하게 볼 수 있습니다. 나는 그것을 분리 된 질문으로 분해 할 것이다. – raphytaffy