我的应用程序有两个包含相同架构的MYSQL数据库,但是两个数据库中的数据都是唯一的(分布式)。 就像假设订单号是偶数一样,它将转到第一个数据库,否则将转到第二个数据库。
# DataSource1
spring.first.datasource.jdbcUrl=jdbc:mysql://localhost:3306/mysqlone?autoReconnect=true&useSSL=false
spring.first.datasource.username=root
spring.first.datasource.password=password
spring.first.datasource.driver-class-name=com.mysql.jdbc.Driver
# DataSource2
spring.second.datasource.jdbcUrl=jdbc:mysql://localhost:3306/mysqltwo?autoReconnect=true&useSSL=false
spring.second.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.second.datasource.username=root
spring.second.datasource.password=password
# JPA / HIBERNATE
spring.first.jpa.show-sql=true
spring.first.jpa.hibernate.ddl-auto=none
spring.first.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.second.jpa.show-sql=true
spring.second.jpa.hibernate.ddl-auto=none
spring.second.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
@Entity
@Table(name="USER_TB")
public class User {
@Id
private int id;
private String name;
}
@Repository
public interface UserRepository extends JpaRepository<User, Integer>{
}
@Configuration
@EnableJpaRepositories(basePackages = {"com.multi.ds.api.repo"},
entityManagerFactoryRef = "ds1EntityManager",
transactionManagerRef = "ds1TransactionManager")
public class DatabaseOne {
@Autowired
private Environment env;
@Bean
public DataSource ds1Datasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.first.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.first.datasource.jdbcUrl"));
dataSource.setUsername(env.getProperty("spring.first.datasource.username"));
dataSource.setPassword(env.getProperty("spring.first.datasource.password"));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean ds1EntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(ds1Datasource());
em.setPackagesToScan(new String[] { "com.multi.ds.api.model" });
em.setPersistenceUnitName("ds1EntityManager");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", env.getProperty("spring.first.jpa.properties.hibernate.dialect"));
properties.put("hibernate.show-sql", env.getProperty("spring.first.jpa.show-sql"));
em.setJpaPropertyMap(properties);
em.afterPropertiesSet();
return em;
}
@Bean
public PlatformTransactionManager ds1TransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(ds1EntityManager().getObject());
return transactionManager;
}
}
@EnableJpaRepositories(basePackages = {"com.multi.ds.api.repo"},
entityManagerFactoryRef = "ds2EntityManager",
transactionManagerRef = "ds2TransactionManager")
public class DatabaseTwo {
@Autowired
private Environment env;
@Bean
public DataSource ds2Datasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.second.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.second.datasource.jdbcUrl"));
dataSource.setUsername(env.getProperty("spring.second.datasource.username"));
dataSource.setPassword(env.getProperty("spring.second.datasource.password"));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean ds2EntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(ds2Datasource());
em.setPackagesToScan(new String[] { "com.multi.ds.api.model" });
em.setPersistenceUnitName("ds2EntityManager");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", env.getProperty("spring.second.jpa.properties.hibernate.dialect"));
properties.put("hibernate.show-sql", env.getProperty("spring.second.jpa.show-sql"));
em.setJpaPropertyMap(properties);
em.afterPropertiesSet();
return em;
}
@Bean
public PlatformTransactionManager ds2TransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(ds2EntityManager().getObject());
return transactionManager;
}
}
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional("${txManager}")
public List<User> getAll(){
return userRepository.findAll();
}
}
@SpringBootApplication
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
@RestController
public class SpringBootMultiDs1Application {
@Autowired
UserService userService;
@RequestMapping(value = "/all", method = RequestMethod.GET)
public List<User> getAll(Long orderNumber){
//if orderNumber is even I need Users from Datasource1 else from Datasource2 USER_TB table
return userService.getAll();
}
public static void main(String[] args) {
SpringApplication.run(SpringBootMultiDs1Application.class, args);
}
}
如果entityManagers拥有自己的jpa存储库,则可以使用。但是在我的情况下,两个entityManagers都具有相同的jpa存储库。 有人可以帮助我吗,有什么方法可以满足我的要求?
答案 0 :(得分:0)
我认为您可以像这样创建基础存储库(未用@Repository
注释)
public interface UserRepository extends JpaRepository<User, Integer> {
}
然后您可以使用两个存储库来扩展基本存储库界面
@Repository
public interface User1Repository extends UserRepository {
}
@Repository
public interface User2Repository extends UserRepository {
}
基础存储库将使您可以在一处定义所有方法。 在使用中,您必须像这样组合两个存储库:
@Service
public class UserService {
private final User1Repository user1Repository;
private final User2Repository user2Repository;
@Autowired
public UserService(User1Repository user1Repository, User2Repository user2Repository) {
this.user1Repository = user1Repository;
this.user2Repository = user2Repository;
}
@Transactional(readOnly = true)
public List<User> getAll(){
return Stream.concat(user1Repository.findAll().stream(), user2Repository.findAll().stream()).collect(Collectors.toList());
}
}