Tavaszi JPA - Több adatbázis

1. Áttekintés

Ebben az oktatóanyagban egy egyszerű tavaszi konfigurációt valósítunk meg a Spring Data JPA rendszer több adatbázissal.

2. Az entitások

Először - hozzunk létre két egyszerű entitást - mindegyik külön adatbázisban él.

Itt van az elsőFelhasználó”Entitás:

com.baeldung.multipledb.model.user csomag; @Entity @Table (schema = "users") public class User {@Id @GeneratedValue (strategy = GenerationType.AUTO) private int id; privát karakterlánc neve; @Column (egyedi = true, nullable = false) privát karakterlánc e-mail; privát int kor; }

És a második entitás -Termék“:

com.baeldung.multipledb.model.product csomag; @Entity @Table (schema = "products") public class Product {@Id private int id; privát karakterlánc neve; magán dupla ár; }

Amint látod, a két entitás független csomagokba is kerül - ez fontos lesz, amikor belépünk a konfigurációba.

3. A KPK adattárai

Ezután - vessünk egy pillantást a JPA két tárházára - UserRepository:

com.baeldung.multipledb.dao.user csomag; nyilvános felület A UserRepository kiterjeszti a JpaRepository {}

És ProductRepository:

csomag com.baeldung.multipledb.dao.product; nyilvános felület A ProductRepository kiterjeszti a JpaRepository {}

Ismét megjegyezzük, hogyan hoztuk létre ezt a két tárolót különböző csomagokban.

4. Konfigurálja a JPA-t Java-val

Következő - térjünk át a tényleges tavaszi konfigurációra. Először két konfigurációs osztályt állítunk fel - egyet a Felhasználó a másik pedig a Termék.

Ezen konfigurációs osztályok mindegyikében meg kell határoznunk a következő interfészeket Felhasználó:

  • Adatforrás
  • EntityManagerFactory (userEntityManager)
  • TransactionManager (userTransactionManager)

Kezdjük azzal, hogy megnézzük a felhasználói konfigurációt:

@Configuration @PropertySource ({"classpath: persistence-multiple-db.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.user", entitásManagerFactoryRef = "userEntityManager", tranzakciómanager "TransactionManagerRef" PersistenceUserConfiguration {@Autowired private Environment env; @Bean @Primary public LocalContainerEntityManagerFactoryBean userEntityManager () {LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean (); em.setDataSource (userDataSource ()); em.setPackagesToScan (új karakterlánc [] {"com.baeldung.multipledb.model.user"}); HibernateJpaVendorAdapter vendorAdapter = új HibernateJpaVendorAdapter (); em.setJpaVendorAdapter (vendorAdapter); HashMap tulajdonságok = új HashMap (); properties.put ("hibernate.hbm2ddl.auto", env.getProperty ("hibernate.hbm2ddl.auto"); properties.put ("hibernate.dialect", env.getProperty ("hibernate.dialect")); em.setJpaPropertyMap (tulajdonságok); vissza em; } @Primary @Bean public DataSource userDataSource () {DriverManagerDataSource dataSource = új 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")); return dataSource; } @Primary @Bean public PlatformTransactionManager userTransactionManager () {JpaTransactionManageractionManager = új JpaTransactionManager (); tranzakcióManager.setEntityManagerFactory (userEntityManager (). getObject ()); visszatérési tranzakcióManager; }}

Figyelje meg, hogyan használjuk a userTransactionManager mint a mienk Elsődleges TransactionManager - a babdefiníciót a @Elsődleges. Ez hasznos, amikor hallgatólagosan vagy kifejezetten beadjuk a tranzakciókezelőt anélkül, hogy név szerint megadnánk, melyiket.

Ezután beszéljük meg PersistenceProductConfiguration - ahol hasonló babot definiálunk:

@Configuration @PropertySource ({"classpath: persistence-multiple-db.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.product", entitásManagerFactoryRef = "productEntityManager", tranzakcióManagerRact PersistenceProductConfiguration {@Autowired private Environment env; @Bean public LocalContainerEntityManagerFactoryBean productEntityManager () {LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean (); em.setDataSource (productDataSource ()); em.setPackagesToScan (új karakterlánc [] {"com.baeldung.multipledb.model.product"}); HibernateJpaVendorAdapter vendorAdapter = új HibernateJpaVendorAdapter (); em.setJpaVendorAdapter (vendorAdapter); HashMap tulajdonságok = new HashMap (); properties.put ("hibernate.hbm2ddl.auto", env.getProperty ("hibernate.hbm2ddl.auto"); properties.put ("hibernate.dialect", env.getProperty ("hibernate.dialect")); em.setJpaPropertyMap (tulajdonságok); vissza em; } @Bean public DataSource productDataSource () {DriverManagerDataSource dataSource = új 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")); return dataSource; } @Bean public PlatformTransactionManager productTransactionManager () {JpaTransactionManageractionManager = új JpaTransactionManager (); tranzakcióManager.setEntityManagerFactory (productEntityManager (). getObject ()); visszatérési tranzakcióManager; }}

5. Egyszerű teszt

Végül - teszteljük a konfigurációinkat.

Kipróbálunk egy egyszerű tesztet azáltal, hogy létrehozunk minden entitás egy példányát, és ellenőrizzük, hogy létrejött-e - ahogyan a következő példában:

@RunWith (SpringRunner.class) @SpringBootTest @EnableTransactionManagement nyilvános osztály 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 ("[e-mail védett]"); user.setAge (20); user = userRepository.save (felhasználó); assertNotNull (userRepository.findOne (user.getId ())); } @Test @Transactional ("userTransactionManager") public void whenCreatingUsersWithSameEmail_thenRollback () {User user1 = new User (); user1.setName ("John"); user1.setEmail ("[e-mail védett]"); user1.setAge (20); user1 = userRepository.save (user1); assertNotNull (userRepository.findOne (user1.getId ())); User user2 = new User (); user2.setName ("Tom"); user2.setEmail ("[e-mail védett]"); user2.setAge (10); próbáld ki a {user2 = userRepository.save (user2) parancsot; } catch (DataIntegrityViolationException e) {} assertNull (userRepository.findOne (user2.getId ())); } @Test @Transactional ("productTransactionManager") public void whenCreatingProduct_thenCreated () {Product product = new Product (); product.setName ("Könyv"); product.setId (2); product.setPrice (20); termék = productRepository.save (termék); assertNotNull (productRepository.findOne (product.getId ())); }}

6. Több adatbázis a tavaszi indításkor

A Spring Boot egyszerűsítheti a fenti konfigurációt.

Alapértelmezés szerint, A Spring Boot példányosítja az alapértelmezett értéket Adatforrás a előtaggal rendelkező konfigurációs tulajdonságokkal tavasz.adatforrás. *:

spring.datasource.jdbcUrl = [url] spring.datasource.username = [felhasználónév] spring.datasource.password = [jelszó]

Most továbbra is ugyanúgy szeretnénk használni konfigurálja a másodikat Adatforrás, de egy másik tulajdonságnévvel:

spring.second-datasource.jdbcUrl = [url] spring.second-datasource.username = [felhasználónév] spring.second-datasource.password = [jelszó]

Mivel azt akarjuk, hogy a Spring Boot automatikus konfiguráció felvegye ezeket a különböző tulajdonságokat (és két különbözőt példányosítson) Adatforrások), két konfigurációs osztályt definiálunk, hasonlóak az előző szakaszokhoz:

@Configuration @PropertySource ({"classpath: persistence-multiple-db-boot.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.user", entitásManagerFactoryRef = "userEntityManager" = tranzakcióManager ", tranzakció" Manager " public class PersistenceUserAutoConfiguration {@Primary @Bean @ConfigurationProperties (prefix = "spring.datasource") public DataSource userDataSource () {return DataSourceBuilder.create (). build (); } // userEntityManager bab // userTransactionManager bab}
@Configuration @PropertySource ({"classpath: persistence-multiple-db-boot.properties"}) @EnableJpaRepositories (basePackages = "com.baeldung.multipledb.dao.product", entitásManagerFactoryRef = "productEntityManager", tranzakció "ManagerManager", tranzakció " public class PersistenceProductAutoConfiguration {@Bean @ConfigurationProperties (prefix = "spring.second-datasource") public DataSource productDataSource () {return DataSourceBuilder.create (). build (); } // productEntityManager bab // productTransactionManager bab} 

Meghatároztuk az adatforrás tulajdonságait belül persistence-multiple-db-boot.properties a Boot automatikus konfigurációs konvenciója szerint.

Az érdekes rész az az adatforrás-bean létrehozási módszerrel történő jelölése @ConfigurationProperties. Csak meg kell adnunk a megfelelő config előtagot. Ezen a módszeren belül a DataSourceBuilder, a Spring Boot pedig automatikusan gondoskodik a többiről.

De hogyan adják be a konfigurált tulajdonságokat a Adatforrás konfiguráció?

Amikor felhívja a épít() módszer a DataSourceBuilder, akkor privátnak fogja hívni kötés () módszer:

public T build () {Osztálytípus = getType (); DataSource eredmény = BeanUtils.instantiateClass (típus); talánGetDriverClassName (); köt (eredmény); visszatérési (T) eredmény; }

Ez a privát módszer az autokonfigurációs varázslat nagy részét végrehajtja, a megoldott konfigurációt a ténylegeshez köti Adatforrás példa:

private void bind (DataSource result) {ConfigurationPropertySource source = new MapConfigurationPropertySource (this.properties); ConfigurationPropertyNameAliases aliases = új ConfigurationPropertyNameAliases (); aliases.addAliases ("url", "jdbc-url"); aliases.addAliases ("felhasználónév", "felhasználó"); Binder kötőanyag = new Binder (forrás.az aliasokkal (álnevek)); binder.bind (ConfigurationPropertyName.EMPTY, Bindable.ofInstance (eredmény)); }

Bár magunknak nem kell megérintenünk ezt a kódot, mégis hasznos tudni, mi történik a Spring Boot autokonfiguráció burkolata alatt.

Emellett a Transaction Manager és az Entity Manager babkonfiguráció megegyezik a szokásos Spring alkalmazással.

7. Következtetés

Ez a cikk gyakorlati áttekintés volt arról, hogyan kell konfigurálni a Spring Data JPA projektet több adatbázis használatára.

A teljes végrehajtása cikkünk megtalálható a GitHub projektben - ez egy Maven-alapú projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.