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