Jarné JPA - viac databáz

1. Prehľad

V tomto výučbe implementujeme jednoduchú jarnú konfiguráciu pre a Systém jarných údajov JPA s viacerými databázami.

2. Subjekty

Najprv - vytvorme dve jednoduché entity - každá žije v samostatnej databáze.

Tu je prvý „Používateľ”Entita:

balíček com.baeldung.multipledb.model.user; @Entity @Table (schema = "users") verejná trieda User {@Id @GeneratedValue (strategy = GenerationType.AUTO) private int id; súkromné ​​meno reťazca; @Column (unique = true, nullable = false) private String email; súkromný int vek; }

A druhá entita - „Výrobok“:

balíček com.baeldung.multipledb.model.product; @Entity @Table (schema = "products") verejná trieda Produkt {@Id private int id; súkromné ​​meno reťazca; dvojitá súkromná cena; }

Ako môžeš vidieť, tieto dva subjekty sú tiež umiestnené v nezávislých balíkoch - to bude dôležité, keď prejdeme do konfigurácie.

3. Úložiská Spoločného parlamentného zhromaždenia

Ďalej - pozrime sa na naše dva úložiská JPA - UserRepository:

balíček com.baeldung.multipledb.dao.user; verejné rozhranie UserRepository rozširuje JpaRepository {}

A Úložisko produktu:

balíček com.baeldung.multipledb.dao.product; verejné rozhranie ProductRepository rozširuje JpaRepository {}

Opäť si všimnite, ako sme vytvorili tieto dva úložiská v rôznych balíkoch.

4. Nakonfigurujte JPA pomocou Javy

Ďalej - poďme k skutočnej jarnej konfigurácii. Začneme nastavením dvoch konfiguračných tried - jednej pre Používateľ a druhý pre Výrobok.

V každej z týchto konfiguračných tried budeme musieť definovať nasledujúce rozhrania pre Používateľ:

  • Dátový zdroj
  • EntityManagerFactory (userEntityManager)
  • TransactionManager (userTransactionManager)

Začnime pohľadom na konfiguráciu používateľa:

@Configuration @PropertySource ({"classpath: persistence-multiple-db.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager" ,actionManagerRef = "user" PersistenceUserConfiguration {@Autowired private Environment env; @Bean @Primary public LocalContainerEntityManagerFactoryBean userEntityManager () {LocalContainerEntityManagerFactoryBean em = nový LocalContainerEntityManagerFactoryBean (); em.setDataSource (userDataSource ()); em.setPackagesToScan (nový reťazec [] {"com.baeldung.multipledb.model.user"}); HibernateJpaVendorAdapter vendorAdapter = nový HibernateJpaVendorAdapter (); em.setJpaVendorAdapter (vendorAdapter); Vlastnosti HashMap = nový HashMap (); properties.put ("hibernate.hbm2ddl.auto", env.getProperty ("hibernate.hbm2ddl.auto")); properties.put ("hibernate.dialect", env.getProperty ("hibernate.dialect")); em.setJpaPropertyMap (vlastnosti); vrátiť em; } @Primary @Bean public DataSource userDataSource () {DriverManagerDataSource dataSource = nový DriverManagerDataSource (); dataSource.setDriverClassName (env.getProperty ("jdbc.driverClassName")); dataSource.setUrl (env.getProperty ("user.jdbc.url")); dataSource.setUsername (env.getProperty ("jdbc.user")); dataSource.setPassword (env.getProperty ("jdbc.pass")); vrátiť dátový zdroj; } @Primary @Bean public PlatformTransactionManager userTransactionManager () {JpaTransactionManageractionManager = nový JpaTransactionManager (); actionManager.setEntityManagerFactory (userEntityManager (). getObject ()); return transactionManager; }}

Všimnite si, ako používame userTransactionManager ako náš Primárny TransactionManager - anotáciou definície fazule pomocou @Primárny. To je užitočné vždy, keď ideme implicitne alebo explicitne vložiť správu transakcií bez toho, aby sme menovite určili, ktorý z nich.

Ďalej poďme diskutovať Konfigurácia produktu PersistenceProductConfiguration - kde definujeme podobné fazule:

@Configuration @PropertySource ({"classpath: persistence-multiple-db.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager" ,actionManagerRef = "productManagerRef =" PersistenceProductConfiguration {@Autowired private Environment env; @Bean public LocalContainerEntityManagerFactoryBean productEntityManager () {LocalContainerEntityManagerFactoryBean em = nový LocalContainerEntityManagerFactoryBean (); em.setDataSource (productDataSource ()); em.setPackagesToScan (nový reťazec [] {"com.baeldung.multipledb.model.product"}); HibernateJpaVendorAdapter vendorAdapter = nový HibernateJpaVendorAdapter (); em.setJpaVendorAdapter (vendorAdapter); Vlastnosti HashMap = nový HashMap (); properties.put ("hibernate.hbm2ddl.auto", env.getProperty ("hibernate.hbm2ddl.auto")); properties.put ("hibernate.dialect", env.getProperty ("hibernate.dialect")); em.setJpaPropertyMap (vlastnosti); vrátiť em; } @Bean public DataSource productDataSource () {DriverManagerDataSource dataSource = nový DriverManagerDataSource (); dataSource.setDriverClassName (env.getProperty ("jdbc.driverClassName")); dataSource.setUrl (env.getProperty ("product.jdbc.url")); dataSource.setUsername (env.getProperty ("jdbc.user")); dataSource.setPassword (env.getProperty ("jdbc.pass")); vrátiť dátový zdroj; } @Bean public PlatformTransactionManager productTransactionManager () {JpaTransactionManager transactionManager = nový JpaTransactionManager (); actionManager.setEntityManagerFactory (productEntityManager (). getObject ()); return transactionManager; }}

5. Jednoduchý test

Nakoniec - otestujme naše konfigurácie.

Vyskúšame jednoduchý test tak, že vytvoríme inštanciu každej entity a uistíme sa, že je vytvorená - ako v nasledujúcom príklade:

@RunWith (SpringRunner.class) @SpringBootTest @EnableTransactionManagement verejná trieda JpaMultipleDBIntegrationTest {@Autowired private UserRepository userRepository; @Autowired private ProductRepository productRepository; @Test @Transactional ("userTransactionManager") public void whenCreatingUser_thenCreated () {User user = new User (); user.setName ("John"); user.setEmail ("[chránený e-mailom]"); user.setAge (20); user = userRepository.save (užívateľ); assertNotNull (userRepository.findOne (user.getId ())); } @Test @Transactional ("userTransactionManager") public void whenCreatingUsersWithSameEmail_thenRollback () {User user1 = new User (); user1.setName ("John"); user1.setEmail ("[chránený e-mailom]"); user1.setAge (20); user1 = userRepository.save (user1); assertNotNull (userRepository.findOne (user1.getId ())); Používateľ user2 = nový používateľ (); user2.setName ("Tom"); user2.setEmail ("[chránený e-mailom]"); user2.setAge (10); try {user2 = userRepository.save (user2); } catch (DataIntegrityViolationException e) {} assertNull (userRepository.findOne (user2.getId ())); } @Test @Transactional ("productTransactionManager") public void whenCreatingProduct_thenCreated () {Product product = new Product (); product.setName ("kniha"); product.setId (2); product.setPrice (20); product = productRepository.save (produkt); assertNotNull (productRepository.findOne (product.getId ())); }}

6. Viac databáz v Spring Boot

Spring Boot môže zjednodušiť vyššie uvedenú konfiguráciu.

Predvolene, Spring Boot vytvorí inštanciu svojho predvoleného nastavenia Dátový zdroj s vlastnosťami konfigurácie pred spring.datasource. *:

spring.datasource.jdbcUrl = [url] spring.datasource.username = [používateľské meno] spring.datasource.password = [heslo]

Teraz chceme používať rovnaký spôsob ako nakonfigurovať druhý Dátový zdroj, ale s iným menným priestorom vlastnosti:

spring.second-datasource.jdbcUrl = [url] spring.second-datasource.username = [používateľské meno] spring.second-datasource.password = [heslo]

Pretože chceme, aby automatická konfigurácia Spring Boot zachytila ​​tieto rôzne vlastnosti (a vytvorila dve odlišné inštancie) Zdroje dát), definujeme dve konfiguračné triedy podobné tým v predchádzajúcich častiach:

@Configuration @PropertySource ({"classpath: persistence-multiple-db-boot.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager" = "userEntityManager" = transakcia "user" verejná trieda PersistenceUserAutoConfiguration {@Primary @Bean @ConfigurationProperties (prefix = "spring.datasource") verejná DataSource userDataSource () {return DataSourceBuilder.create (). build (); } // bean userEntityManager // bean userTransactionManager}
@Configuration @PropertySource ({"classpath: persistence-multiple-db-boot.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager" = "productEntityManager" = transakcia ")" verejná trieda PersistenceProductAutoConfiguration {@Bean @ConfigurationProperties (prefix = "spring.second-datasource") verejná DataSource productDataSource () {return DataSourceBuilder.create (). build (); } // fazuľa productEntityManager // fazuľa productTransactionManager} 

Vo vnútri sme definovali vlastnosti zdroja údajov persistence-multiple-db-boot.properties podľa konvencie Boot auto-configuration.

Zaujímavá časť je anotácia metódy vytvárania fazule zdroja údajov pomocou @ConfigurationProperties. Musíme len určiť príslušnú predponu konfigurácie. V tejto metóde používame a DataSourceBuilder, o ostatné sa automaticky postará Spring Boot.

Ale ako sa nakonfigurované vlastnosti vstreknú do Dátový zdroj konfigurácia?

Pri volaní na build () metóda na DataSourceBuilder, bude sa nazývať súkromná bind () metóda:

public T build () {Class type = getType (); Výsledok zdroja údajov = BeanUtils.instantiateClass (typ); MožnoGetDriverClassName (); viazať (výsledok); návratový (T) výsledok; }

Táto súkromná metóda vykonáva väčšinu mágie automatickej konfigurácie a viaže vyriešenú konfiguráciu na skutočnú Dátový zdroj inštancia:

private void bind (výsledok DataSource) {ConfigurationPropertySource source = new MapConfigurationPropertySource (this.properties); ConfigurationPropertyNameAliases aliasy = nový ConfigurationPropertyNameAliases (); aliases.addAliases ("url", "jdbc-url"); aliases.addAliases ("používateľské meno", "užívateľ"); Binder binder = nový Binder (source.withAliases (aliasy)); binder.bind (ConfigurationPropertyName.EMPTY, Bindable.ofInstance (výsledok)); }

Aj keď sa nemusíme sami dotýkať žiadneho z týchto kódov, je stále užitočné vedieť, čo sa deje pod kapotou automatickej konfigurácie Spring Boot.

Okrem toho je konfigurácia fazule Transaction Manager a Entity Manager rovnaká ako štandardná aplikácia Spring.

7. Záver

Tento článok bol praktickým prehľadom toho, ako nakonfigurovať váš projekt Spring Data JPA tak, aby používal viac databáz.

The úplná implementácia tohto článku nájdete v projekte GitHub - jedná sa o projekt založený na Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.