如何使用相同的实体通过 spring 引导连接 3 个数据库?

How to use the same entities to connect on 3 databases with spring boot?

自上周以来我遇到了一个问题,我到处搜索都没有找到解决方案...我是瞎了吗?

我目前正在使用 Spring Boot 开发 Java Web 应用程序。我有 3 个具有相同结构但不相同数据的 Oracle 数据库,因为每个数据库都在特定环境中工作。
我在 "how to use multiple datasources" 上找到了很多提示,但它们都谈论具有特定实体的不同数据源(例如 "user" 和 "order")。所以他们没有解决我的问题。

因为我的 3 个数据库具有相同的结构,所以我希望能够使用我的实体并在我的所有数据库上搜索结果。

所以我尝试像这样配置应用程序:

@Configuration
public class OracleConfiguration {

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

    @Bean
    @ConfigurationProperties(prefix="datasource.homologation")
    public DataSource homologationDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix="datasource.production")
    public DataSource productionDataSource() {
        return DataSourceBuilder.create().build();
    }
}

并将配置参数放入我的 application.yml :

# Hibernate configuration
spring:
  jpa:
    database-platform: org.hibernate.dialect.Oracle10gDialect
datasource:
  # Oracle configuration for "recette" database
  recette:
    url: "myURL_recette"
    username: "userR"
    password: "pwdR"
    driver-class-name: "oracle.jdbc.OracleDriver"

  # Oracle configuration for "homologation" database
  homologation:
    url: "myURL_hom"
    username: "userH"
    password: "pwdH"
    driver-class-name: "oracle.jdbc.OracleDriver"

  # Oracle configuration for "production" database
  production:
    url: "myURL_Prod"
    username: "userP"
    password: "pwdP"
    driver-class-name: "oracle.jdbc.OracleDriver"

有了这个,我可以访问第一个注册的数据库,但不能访问另外两个。

有人有解决方案或关于如何执行此操作的任何想法吗? 如果我不够清楚,我会改写或添加细节。

编辑:添加了主要 class,其中 Spring 自动装配 bean:

@SpringBootApplication
@EnableAutoConfiguration
public class App {
    public static void main(String[] args) {
        System.out.println("My App ...");
        SpringApplication.run(App.class, args);
    }
}

编辑:添加实体示例:

@Entity
@Table(name = "UPSTREAM")
@IdClass(UpstreamPK.class)
public class Upstream implements Serializable {
    private int numins;
    private String name;

    @Id
    @Column(name = "NUMINS", nullable = false, precision = 0)
    public int getNumins() {
        return numins;
    }

    public void setNumins(int numins) {
        this.numins = numins;
    }

    @Id
    @Column(name = "NAME", nullable = false, length = 150)
    public String getName() {
        return nomfic;
    }

    public void setName(String name) {
        this.name = name;
    }
}

存储库:

@Transactional
public interface UpstreamRepository extends CrudRepository<Upstream, Long> {
}

服务:

@Service(value = "upstreamService")
public class UpstreamServiceImpl implements UpstreamService {

    @PersistenceContext
    private EntityManager em;

    @Resource
    private UpstreamRepository upstreamRepository;

    @Override
    public Upstream findOne(final String filename) {
        final CriteriaBuilder cb = em.getCriteriaBuilder();
        final CriteriaQuery<Upstream> cq = cb.createQuery(Upstream.class);
        final Root<Upstream> root = cq.from(Upstream.class);
        final EntityType<Upstream> entityType = root.getModel();

        cq.select(root);
        Predicate where = cb.conjunction();

        if (filename != null && !filename.isEmpty()) {
            // Add predicate for "name"
            final Predicate namePredicate = root.get(entityType.getSingularAttribute("name")).in(filename);
            where = cb.and(where, namePredicate);
        }

        // Query creation
        cq.where(where);
        final TypedQuery<Upstream> q = em.createQuery(cq);

        return q.getSingleResult();
    }

    public UpstreamRepository getUpstreamRepository() {
        return upstreamRepository;
    }

    public void setUpstreamRepository(final UpstreamRepository upstreamRepository) {
        this.upstreamRepository = upstreamRepository;
    }
}

你现在在做什么:

您创建了 3 个数据源 bean。其中之一有 @Primary 注释,正如 springBoot doc 所说:

如果您正在使用 JDBC 或 JPA 的默认自动配置(那么任何 @Autowired 注入都会选择该配置)。

这里

@PersistenceContext
private EntityManager em;

EM 使用@Primary 上下文。

应该如何:

您应该创建 3 个自定义 EM 并为每个 EM 手动指定数据源。他们每个人都会有这样的属性:

 <property name="persistenceUnitName" value="name" />
 <property name="dataSource" ref="dataSource" />

然后你应该将 EM 注入你的 DAO class 并在 for 循环中调用每个 EM。

@PersistenceContext(unitName="name")
private EntityManager entityManager;

有用的文章: http://www.codingpedia.org/ama/how-to-setup-multiple-data-sources-with-spring-and-jpa/

通过 java spring 配置创建 EM: http://www.baeldung.com/2011/12/13/the-persistence-layer-with-spring-3-1-and-jpa/