Giriş
İzlenmesi gereken adımların sırası şöyle
1. İki tane DataSource yaratılır. Bir tanesi @Primary olarak işaretlenir.2. İki tane LocalContainerEntityManagerFactoryBean yaratılır. Bir tanesi @Primary olarak işaretlenir. Her birisine ilgili DataSource atanır3. @EnableJpaRepositories anotasyonunda ilgili LocalContainerEntityManagerFactoryBean ve PlatformTransactionManager belirtilir. basePackages ile hangi sınıfların kullanılacağı belirtilir. Gerekiyorsa excludeFilters ile hangi JPA sınıflarının kullanılmayacağı belirtilir.
Bir örnek burada.
Örnek - Master ve Slave DB Ayrımı
Birinci veri tabanı konfigürasyonu için şöyle yaparız. Burada excludeFilters alanı önemli.
İkinci veri tabanı konfigürasyonu için şöyle yaparız. Burada includeFilters alanı önemli.@Configuration@EnableJpaRepositories(basePackages = "...",excludeFilters = @ComponentScan.Filter(ReadOnlyRepository.class),entityManagerFactoryRef = "primaryEntityManagerFactory")public class PrimaryDataSourceConfiguration {@Bean@Primarypublic DataSource primaryDataSource() {...}@Bean@Primarypublic LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory() {...}}
@Configuration@EnableJpaRepositories(basePackages = "...",includeFilters = @ComponentScan.Filter(ReadOnlyRepository.class),entityManagerFactoryRef = "readOnlyEntityManagerFactory")public class ReadOnlyDataSourceConfiguration {@Beanpublic DataSource readDataSource() {...}@Beanpublic LocalContainerEntityManagerFactoryBean readOnlyEntityManagerFactory() {...}}
Seçim için kullanılacak anotasyon şöyledir
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Documentedpublic @interface ReadOnlyRepository {}
Entity ve Repository sınıfları şöyledir
@Entity@Table(name = "books")@Datapublic class Books {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;...}@Repository@ReadOnlyRepositorypublic interface BooksReadOnlyRepository extends JpaRepository<Books, Long> {}@Repositorypublic interface BooksReadWriteRepository extends JpaRepository<Books, Long> {}
Bunları kullanmak için şöyle yaparız
@Repositorypublic class BooksDAO implements BooksReadOnlyRepository, BooksReadWriteRepository {private BooksReadOnlyRepository booksReadOnlyRepository;private BooksReadWriteRepository booksReadWriteRepository;@Autowiredpublic BooksDAO(BooksReadOnlyRepository booksReadOnlyRepository,
BooksReadWriteRepository booksReadWriteRepository) {this.booksReadOnlyRepository = booksReadOnlyRepository;this.booksReadWriteRepository = booksReadWriteRepository;}public List<Books> getAllBooksFromMaster() {return booksReadWriteRepository.findAll();}public List<Books> getAllBooksFromSlave() {return booksReadOnlyRepository.findAll();}...}
Örnek
application.properties şöyle olsun. Burada bir bağlantı normal Spring kuralları ile yapılıyor. Test için olan JPA ise elle kodlanıyor
#DataSource spring.test1.jdbc-url=jdbc:mysql://localhost:3306/test1 spring.test1.username=root spring.test1.password=root@1234 spring.test1.driverClassName=com.mysql.cj.jdbc.Driver spring.test2.jdbc-url=jdbc:mysql://localhost:3306/test2 spring.test2.username=root spring.test2.password=root@1234 spring.test2.driverClassName=com.mysql.cj.jdbc.Driver #JPA spring.jpa.hibernate.ddl-auto=validate spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect spring.jpa.properties.hibernate.format_sql=true
Test bağlantısı için şöyle yaparız
import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef = "personEntityManagerfactoryBean", transactionManagerRef = "personTransactionManager", basePackages = {"com.spring.boot.multipledatabase.repo.person"} ) public class Test2DbConfig { @Bean(name = "test2DataSource") @ConfigurationProperties(prefix = "spring.test2") public DataSource test1Datasource() { return DataSourceBuilder.create().build(); } @Bean(name = "personEntityManagerfactoryBean") public LocalContainerEntityManagerFactoryBean entityManagerfactoryBean( EntityManagerFactoryBuilder builder, @Qualifier("test2DataSource") DataSource dataSource) { return builder.dataSource(dataSource) .packages("com.spring.boot.multipledatabase.entity.person") .persistenceUnit("PERSON") .build(); } @Bean(name = "personTransactionManager") public PlatformTransactionManager transactionManager( @Qualifier("personEntityManagerfactoryBean") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } }
Örnek
application.properties şöyle olsun. Kodla iki tane JPA bağlantısı açacağız
#Primary database connection spring.primary.datasource.url = jdbc:postgresql://localhost:5432/MultipleDbDemo spring.primary.datasource.username = postgres spring.primary.datasource.password = 1234 #Secondary database connection spring.secondary.datasource.url = jdbc:sqlserver://localhost:1433;databaseName=MultipleDbDemoSqlServer;encrypt=true;trustServerCertificate=true spring.secondary.datasource.username = sa spring.secondary.datasource.password = 1234 #spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.SQLServerDialect spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.show-sql=true spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true spring.jpa.properties.javax.persistence.validation.mode = none server.port:3000
Birinci bağlantı için şöyle yaparız. Burada önemli olan JPA modellerini farklı bir pakette toplamak
@Configuration @EnableJpaRepositories(entityManagerFactoryRef = "primaryEntityManagerFactory", transactionManagerRef = "primaryTransactionManager", basePackages = {"merveozer.multipledb.primary.repository"}) public class PrimaryDatabaseConnection { @Value("${spring.primary.datasource.url}") private String url; @Value("${spring.primary.datasource.username}") private String username; @Value("${spring.primary.datasource.password}") private String password; @Primary @Bean(name="primaryDbDataSource") public DataSource primaryDbDataSource() { return DataSourceBuilder.create() .url(url).username(username).password(password).build(); } @Primary @Bean(name = "primaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("primaryDbDataSource") DataSource primaryDataSource) { return builder.dataSource(primaryDataSource) .packages("merveozer.multipledb.primary.model") .build(); } @Primary @Bean(name = "primaryTransactionManager") public PlatformTransactionManager primaryTransactionManager( @Qualifier("primaryEntityManagerFactory") EntityManagerFactory primaryEntityManagerFactory) { return new JpaTransactionManager(primaryEntityManagerFactory); } }
İkinci bağlantı için de şöyle yaparız. JPA modelleri yine farklı bir pakette.
@Configuration @EnableJpaRepositories(entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager", basePackages = {"merveozer.multipledb.secondary.repository"}) public class SecondaryDatabaseConnection { @Value("${spring.secondary.datasource.url}") private String url; @Value("${spring.secondary.datasource.username}") private String username; @Value("${spring.secondary.datasource.password}") private String password; @Bean(name="secondaryDbDataSource") public DataSource secondaryDbDataSource() { return DataSourceBuilder.create().url(url) .username(username).password(password).build(); } @Bean(name = "secondaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory( @Qualifier("secondaryDbDataSource") DataSource secondaryDataSource, EntityManagerFactoryBuilder builder) { return builder.dataSource(secondaryDataSource) .packages("merveozer.multipledb.secondary.model").build(); } @Bean(name = "secondaryTransactionManager") public PlatformTransactionManager secondaryTransactionManager( @Qualifier("secondaryEntityManagerFactory") EntityManagerFactory secondaryEntityManagerFactory) { return new JpaTransactionManager(secondaryEntityManagerFactory); } }
Hiç yorum yok:
Yorum Gönder