如何使用相同的实体通过 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/
自上周以来我遇到了一个问题,我到处搜索都没有找到解决方案...我是瞎了吗?
我目前正在使用 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/