rjbtechnology.com/blog/2017-01/...

я есть проект Spring Boot с одной сущностью и одним хранилищем, связанным с этой сущностью. В репозитории есть один метод с пользовательским запросом, а в контроллере проекта этот репозиторий используется для возврата данных из разных баз данных postgresql. В этих базах данных есть одинаковые таблицы с одинаковыми столбцами (так что упомянутый объект одинаков), единственное различие между этими базами данных - это год (..., DB2015, DB2016, DB2017). Мои вопросы: Как я могу вернуть данные в контроллере проекта, которые принадлежат «различным» базам данных? Можно ли использовать один и тот же запрос для выбора данных сначала из первой базы данных, затем из второй и так далее? В других вопросах я читал, что мне нужны разные источники данных, это правильно?

Это сущность:

@Entity(name = "REQUEST")
public class Request implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Id
@Column(name="IDREQUEST", nullable=false)
private BigDecimal idrequest;


@Column(name="PAYLOAD")
private String payload;

@Column(name="MITTENTE")
private String mittente;

@Column(name="SERVIZIO")
private String servizio;

@Column(name="DATARICEZIONE")
private BigDecimal dataricezione;

public BigDecimal getIdrequest() {
    return idrequest;
}

public void setIdrequest(BigDecimal idrequest) {
    this.idrequest = idrequest;
}

public String getPayload() {
    return payload;
}

public void setPayload(String payload) {
    this.payload = payload;
}

public String getMittente() {
    return mittente;
}

public void setMittente(String mittente) {
    this.mittente = mittente;
}

public String getServizio() {
    return servizio;
}

public void setServizio(String servizio) {
    this.servizio = servizio;
}

public BigDecimal getDataricezione() {
    return dataricezione;
}

public void setDataricezione(BigDecimal dataricezione) {
    this.dataricezione = dataricezione;
}

}

Это хранилище:

@Repository
public interface RequestRepository extends PagingAndSortingRepository<Request, BigDecimal> {

    @Query(nativeQuery=true, value="SELECT * FROM \"REQUEST\" WHERE strpos(\"PAYLOAD\",\'?1\') > 0")
    List<Request> findByCodiceFiscale(String codiceFiscale);

}

Это контроллер

@RequestMapping(value="/ricercaadesioni/{codicefiscale}", method=RequestMethod.GET)
public ResponseEntity<List<Request>> ricercaAdesioniByCodiceFIscale(@PathVariable("codicefiscale") String codicefiscale) {

    List<Request> listAdesioni = requestRepo.findByCodiceFiscale(codicefiscale);

    return new ResponseEntity<List<Request>>(listAdesioni, HttpStatus.OK);
}

Это application.properties (в этом случае источник данных относится только к одной базе данных):

spring.datasource.url=jdbc:postgresql://localhost:5432/DB2017_test
spring.datasource.username=xxx
spring.datasource.password=xxx

Надеюсь все понятно

 mrkernelpanic18 окт. 2017 г., 12:58
Вы можете определить несколькоLocalContainerEntityManagerFactoryBeanbean-компоненты, каждый из которых имеет источник данных, связанный с требуемой базой данных.

Ответы на вопрос(1)

Решение Вопроса

и эти 2 файла конфигурации будут иметь разные спецификации для 2 разных классов репозитория jpa. Но они могут иметь один и тот же класс домена.

step1> В вашем файле свойств есть 2 детали источника данных.

spring.datasource.url=jdbc:postgresql://localhost:5432/DB2017_test
spring.datasource.username=xxx
spring.datasource.password=xxx


# DB2018 DB - ""
spring.datasource2.url=jdbc:postgresql://localhost:5432/DB2018_test
spring.datasource2.username=xxx
spring.datasource2.password=xxx

step2> Затем создайте файл конфигурации для первого источника данных

package com.package1;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "entityManagerFactory",
  basePackages = { "com.package1.repo" } 
)
public class DB2017Config {

  @Primary
  @Bean(name = "dataSource")
  @ConfigurationProperties(prefix = "spring.datasource")
  public DataSource dataSource() {
    return DataSourceBuilder.create().build();
  }

  @Primary
  @Bean(name = "entityManagerFactory")
  public LocalContainerEntityManagerFactoryBean 
  entityManagerFactory(
    EntityManagerFactoryBuilder builder,
    @Qualifier("dataSource") DataSource dataSource
  ) {
    return builder
      .dataSource(dataSource)
      .packages("com.domain")
      .persistenceUnit("foo")
      .build();
  }

  @Primary
  @Bean(name = "transactionManager")
  public PlatformTransactionManager transactionManager(
    @Qualifier("entityManagerFactory") EntityManagerFactory 
    entityManagerFactory
  ) {
    return new JpaTransactionManager(entityManagerFactory);
  }
}

step3> Аналогично создайте другой файл конфигурации для другого источника данных,

@EnableJpaRepositories(
  entityManagerFactoryRef = "entityManagerFactory",
  basePackages = { "com.package2.repo" }

И изменить префикс

@ConfigurationProperties(prefix = "spring.datasource2")

Теперь у вас будет 2 похожих RequestRepository1 и RequestRepository2 в package1 и package2 соответственно, как упомянуто выше (basePackages = {"com.package1.repo"}).

step4> Все настроено на autowire 2 разных репо.

@Autowired
private final RequestRepository1  repo1;
@Autowired
private final RequestRepository2  repo2;

Тогда используйте их.

List<Request> listAdesioni = repo1.findByCodiceFiscale(codicefiscale);
List<Request> listAdesioni = repo2.findByCodiceFiscale(codicefiscale);
 cactuschibre25 июн. 2018 г., 17:54
Он немного староват ... Всегда рекомендуется? Я боюсь использовать ThreadLocal. Это совместимо с контекстом транзакции? ...
 surya25 июн. 2018 г., 18:02
Согласен, я тоже не предпочитаю
 cactuschibre25 июн. 2018 г., 17:33
У меня есть 6 разных источников данных для 1 модели ... Есть ли лучшее решение, чем дубликаты репозиториев?
 surya25 июн. 2018 г., 17:39
 cactuschibre27 июн. 2018 г., 09:57
Я нашел несколько замечательных ресурсов по этому поводу. На самом деле, это кажется лучшим решением. Ресурсы :tech.asimio.net/2017/01/17/... а такжеrjbtechnology.com/blog/2017-01/....

Ваш ответ на вопрос