Proljetni JPA - Više baza podataka

1. Pregled

U ovom uputstvu implementirat ćemo jednostavnu proljetnu konfiguraciju za Spring Data JPA sustav s više baza podataka.

2. Entiteti

Prvo - stvorimo dva jednostavna entiteta - svaki živi u zasebnoj bazi podataka.

Evo prvog “Korisnik”Entitet:

paket com.baeldung.multipledb.model.user; @Entity @Table (schema = "users") korisnik javne klase {@Id @GeneratedValue (strategy = GenerationType.AUTO) private int id; privatni naziv niza; @Kolona (jedinstvena = istinita, nullable = false) privatna String adresa e-pošte; privatno int doba; }

A drugi entitet - "Proizvod“:

paket com.baeldung.multipledb.model.product; @Entity @Table (schema = "products") proizvod javne klase {@Id private int id; privatni naziv niza; privatna dvostruka cijena; }

Kao što vidiš, ta su dva entiteta također smještena u neovisne pakete - ovo će biti važno dok prelazimo u konfiguraciju.

3. Spremišta JPA

Dalje - pogledajmo naša dva JPA spremišta - UserRepository:

paket com.baeldung.multipledb.dao.user; javno sučelje UserRepository proširuje JpaRepository {}

I Spremište proizvoda:

paket com.baeldung.multipledb.dao.product; javno sučelje ProductRepository proširuje JpaRepository {}

Opet imajte na umu kako smo stvorili ta dva spremišta u različitim paketima.

4. Konfigurirajte JPA s Javom

Dalje - idemo na stvarnu konfiguraciju Spring. Započet ćemo postavljanjem dvije konfiguracijske klase - jedne za Korisnik a drugi za Proizvod.

U svakoj od ovih konfiguracijskih klasa trebat ćemo definirati sljedeća sučelja za Korisnik:

  • Izvor podataka
  • EntityManagerFactory (userEntityManager)
  • TransactionManager (userTransactionManager)

Počnimo s gledanjem korisničke konfiguracije:

@Configuration @PropertySource ({"classpath: persistence-multiple-db.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager" ,actionManagerRef = " PersistenceUserConfiguration {@Autowired private Environment env; @Bean @Primary public LocalContainerEntityManagerFactoryBean userEntityManager () {LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean (); em.setDataSource (userDataSource ()); em.setPackagesToScan (novi niz [] {"com.baeldung.multipledb.model.user"}); HibernateJpaVendorAdapter vendorAdapter = novo HibernateJpaVendorAdapter (); em.setJpaVendorAdapter (vendorAdapter); Svojstva HashMap = novi HashMap (); svojstva.put ("hibernate.hbm2ddl.auto", env.getProperty ("hibernate.hbm2ddl.auto")); svojstva.put ("hibernate.dialect", env.getProperty ("hibernate.dialect")); em.setJpaPropertyMap (svojstva); vratiti ih; } @Primary @Bean javni DataSource userDataSource () {DriverManagerDataSource dataSource = novi 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")); vratiti dataSource; } @Primary @Bean javni PlatformTransactionManager userTransactionManager () {JpaTransactionManageractionManager = novi JpaTransactionManager (); actionManager.setEntityManagerFactory (userEntityManager (). getObject ()); vratiti transakcijuManager; }}

Primijetite kako koristimo userTransactionManager kao naš Primarni TransactionManager - označavanjem definicije graha s @ Primarno. To je korisno kad god implicitno ili eksplicitno ubrizgamo upravitelja transakcija bez navođenja kojeg po imenu.

Dalje, razgovarajmo PersistentProductConfiguration - gdje definiramo sličan grah:

@Configuration @PropertySource ({"classpath: persistence-multiple-db.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager" ,actionManagerRef = " PersistenceProductConfiguration {@Autowired private Environment env; @Bean public LocalContainerEntityManagerFactoryBean productEntityManager () {LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean (); em.setDataSource (productDataSource ()); em.setPackagesToScan (novi niz [] {"com.baeldung.multipledb.model.product"}); HibernateJpaVendorAdapter vendorAdapter = novo HibernateJpaVendorAdapter (); em.setJpaVendorAdapter (vendorAdapter); Svojstva HashMap = novi HashMap (); svojstva.put ("hibernate.hbm2ddl.auto", env.getProperty ("hibernate.hbm2ddl.auto")); svojstva.put ("hibernate.dialect", env.getProperty ("hibernate.dialect")); em.setJpaPropertyMap (svojstva); vratiti ih; } @Bean public DataSource productDataSource () {DriverManagerDataSource dataSource = novi 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")); vratiti dataSource; } @Bean public PlatformTransactionManager productTransactionManager () {JpaTransactionManageractionManager = new JpaTransactionManager (); actionManager.setEntityManagerFactory (productEntityManager (). getObject ()); vratiti transakcijuManager; }}

5. Jednostavan test

Napokon - testirajmo naše konfiguracije.

Pokušat ćemo s jednostavnim testom stvaranjem instance svakog entiteta i osigurati da je stvorena - kao u sljedećem primjeru:

@RunWith (SpringRunner.class) @SpringBootTest @EnableTransactionManagement javna klasa JpaMultipleDBIntegrationTest {@Autowired private UserRepository userRepository; @Autowired privatni ProductRepository productRepository; @Test @Transactional ("userTransactionManager") javna praznina kadaCreatingUser_thenCreated () {Korisnik korisnik = novi korisnik (); user.setName ("Ivan"); user.setEmail ("[e-pošta zaštićena]"); user.setAge (20); user = userRepository.save (korisnik); assertNotNull (userRepository.findOne (user.getId ())); } @Test @Transactional ("userTransactionManager") javna praznina whenCreatingUsersWithSameEmail_thenRollback () {Korisnik user1 = novi korisnik (); user1.setName ("Ivan"); user1.setEmail ("[e-pošta zaštićena]"); user1.setAge (20); user1 = userRepository.save (user1); assertNotNull (userRepository.findOne (user1.getId ())); Korisnik user2 = novi korisnik (); user2.setName ("Tom"); user2.setEmail ("[e-pošta zaštićena]"); user2.setAge (10); pokušajte {user2 = userRepository.save (user2); } catch (DataIntegrityViolationException e) {} assertNull (userRepository.findOne (user2.getId ())); } @Test @Transactional ("productTransactionManager") javna praznina pri stvaranjuProduct_thenCreated () {Product product = new Product (); product.setName ("Knjiga"); product.setId (2); product.setPrice (20); product = productRepository.save (proizvod); assertNotNull (productRepository.findOne (product.getId ())); }}

6. Više baza podataka u proljetnom pokretanju

Spring Boot može pojednostaviti gornju konfiguraciju.

Prema zadanim postavkama, Spring Boot instancirat će zadane vrijednosti Izvor podataka s konfiguracijskim svojstvima s prefiksom proljeće.dataizvor. *:

spring.datasource.jdbcUrl = [url] spring.datasource.username = [korisničko ime] spring.datasource.password = [lozinka]

Sada želimo nastaviti koristiti isti način na koji konfigurirati drugi Izvor podataka, ali s različitim prostorom imena svojstava:

spring.second-datasource.jdbcUrl = [url] spring.second-datasource.username = [korisničko ime] spring.second-datasource.password = [lozinka]

Budući da želimo da autokonfiguracija Spring Boot pokupi ta različita svojstva (i uspostavi dva različita Izvori podataka), definirat ćemo dvije klase konfiguracije slične onima u prethodnim odjeljcima:

@Configuration @PropertySource ({"classpath: persistence-multiple-db-boot.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager" = "" javna klasa PersistenceUserAutoConfiguration {@Primary @Bean @ConfigurationProperties (prefix = "spring.datasource") public 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" =actionManagerRef "productManagerRef" javna klasa PersistenceProductAutoConfiguration {@Bean @ConfigurationProperties (prefix = "spring.second-datasource") public DataSource productDataSource () {return DataSourceBuilder.create (). build (); } // // productEntityManager bean // productTransactionManager bean} 

Unutar smo definirali svojstva izvora podataka postojanost-višestruki-db-čizma.svojstva prema konvenciji Boot auto-configuration.

Zanimljiv dio je označavajući način stvaranja graha izvora podataka s @ConfigurationProperties. Samo trebamo navesti odgovarajući konfiguracijski prefiks. Unutar ove metode koristimo DataSourceBuilder, a Spring Boot automatski će se pobrinuti za ostalo.

Ali kako se konfigurirana svojstva ubrizgavaju u Izvor podataka konfiguracija?

Kada zovete izgraditi() metoda na DataSourceBuilder, nazvat će ga privatnim vezati() metoda:

javna T gradnja () {Vrsta klase = getType (); Rezultat DataSource = BeanUtils.instantiateClass (vrsta); moždaGetDriverClassName (); vezati (rezultat); povratni (T) rezultat; }

Ova privatna metoda izvodi velik dio magije autokonfiguracije, vezujući razriješenu konfiguraciju za stvarnu Izvor podataka primjer:

privatna void veza (rezultat DataSource) {ConfigurationPropertySource source = new MapConfigurationPropertySource (this.properties); ConfigurationPropertyNameAliases = aliasovi = novi ConfigurationPropertyNameAliases (); aliases.addAliases ("url", "jdbc-url"); aliases.addAliases ("korisničko ime", "korisnik"); Binder binder = novo Binder (source.withAliases (aliasi)); binder.bind (ConfigurationPropertyName.EMPTY, Binvable.ofInstance (rezultat)); }

Iako ne moramo sami dodirivati ​​bilo koji od ovog koda, korisno je znati što se događa ispod haube autokonfiguracije Spring Boot.

Osim toga, konfiguracija graha Transaction Manager i Entity Manager ista je kao i standardna aplikacija Spring.

7. Zaključak

Ovaj je članak bio praktični pregled konfiguriranja vašeg Spring Data JPA projekta za upotrebu više baza podataka.

The puna provedba ovog članka može se naći u projektu GitHub - ovo je projekt zasnovan na Mavenu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.