2017-12-19 47 views
1

여러 데이터베이스에서 같은 개체를 모델링. 단순화를 위해 두 개의 다른 데이터베이스를 가정 해 봅시다.봄 부팅 : <code>EMP_DB1</code>, <code>EMP_DB2</code>, <code>EMP_DB3</code>, <code>EMP_DBx</code> : 나는 다른 데이터베이스에 dblinks을 가지고 하나의 데이터베이스 <code>MAIN_DB</code>가 DBLINK

EMP_DB1EMP_DB2 모두 동일한 테이블 구조와 테이블 EMPLOYEE 있습니다

create table employee(
id number primary key, 
first_name varchar2(40), 
last_name varchar2(40)); 

MAIN_DB 통해 EMP_DB1EMP_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 
} 

내 질문은 무엇으로 귀결 봄 - 완전히 완료 한 최고의 디자인과 어떻게 이것을 할 수 있습니까?

+0

나는 이것이 너무 광범위하고 의견이 모호한 경계에 있다고 생각합니다. [mcve]와 코드 입력을 최소화하는 방법을 고려해보십시오. – GhostCat

+0

@GhostCat 완전성을 위해 노력한 여러 가지를 추가했지만 너무 광범위하게 볼 수 있습니다. 나는 그것을 분리 된 질문으로 분해 할 것이다. – raphytaffy

답변