sql >> データベース >  >> RDS >> Mysql

異なるデータベース間でデータをコピーします(どちらもjdbcをサポートしています)

    確かに、スキーマが同じであれば、非常に簡単な方法で可能です。また、同じHibernateマッピングを使用して両方のデータベースを作成したため、Entityでは同じである必要があります。 センス。

    必要なHibernate永続性ユニット(データソース)は2つだけです。両方が適切に構成されていて、特定のEntityManagerがある場合 インスタンスは便利です。HibernateのSessionに移動するだけです。 レベル-私が知る限り、JPAはこの方法でそれをサポートしていません(私が間違っている場合は訂正してください)-そしてソースエンティティをターゲットデータベースに複製します。

    Springを使用するのが好きなので、次の例ではSpringBootを使用します。構成を除いて、レプリケーションステップは他のHibernateアプリケーションと同じように実装されます。

    また、単純にするために、HSQLBの代わりに2つのPostgreSQLデータベースを使用しています。構成がばらばらになっている場合は、構成部分を拡張するだけです。永続化ユニット間の唯一の違いは、データソースのURLです。

    したがって、最初にレプリケーションをテストするエンティティが必要です:

    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    @Entity
    public class StorageEntry {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String someValue;
    
        // imagine getters and setter here
    
    }
    

    これは、2つのデータソース(のYAMLバージョン)の構成です(targetDatabaseUrlと呼ばれる2番目のデータソースURLを参照してください)。 )、構成の他のすべての部分は、両方の永続性ユニットに使用されます:

    spring:
      datasource:
        url: jdbc:postgresql://localhost/postgres
        targetDatabaseUrl: jdbc:postgresql://localhost/postgres2
        username: <username>
        password: <password>
        driver-class-name: org.postgresql.Driver
      jpa:
        database-platform: org.hibernate.dialect.PostgreSQLDialect
        hibernate:
          ddl-auto: create-drop
    

    次の部分は、データソースの構成クラスです。

    import java.util.Properties;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jdbc.datasource.DriverManagerDataSource;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.JpaVendorAdapter;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.transaction.PlatformTransactionManager;
    
    @Configuration
    public class PersistenceConfig {
    
        @Autowired
        private JpaVendorAdapter jpaVendorAdapter;
    
        @Value("${spring.datasource.url}")
        private String databaseUrl;
    
        @Value("${spring.datasource.targetDatabaseUrl}")
        private String targetDatabaseUrl;
    
        @Value("${spring.datasource.username}")
        private String username;
    
        @Value("${spring.datasource.password}")
        private String password;
    
        @Value("${spring.datasource.driver-class-name}")
        private String driverClassName;
    
        @Value("${spring.jpa.database-platform}")
        private String dialect;
    
        @Value("${spring.jpa.hibernate.ddl-auto}")
        private String ddlAuto;
    
        @Bean
        public EntityManager sourceEntityManager() {
            return sourceEntityManagerFactory().createEntityManager();
        }
    
        @Bean
        public EntityManager targetEntityManager() {
            return targetEntityManagerFactory().createEntityManager();
        }
    
        @Bean
        public EntityManagerFactory sourceEntityManagerFactory() {
            return createEntityManagerFactory("source", databaseUrl);
        }
    
        @Bean
        public EntityManagerFactory targetEntityManagerFactory() {
            return createEntityManagerFactory("target", targetDatabaseUrl);
        }
    
        @Bean
        public PlatformTransactionManager sourceTransactionManager() {
            return new JpaTransactionManager(sourceEntityManagerFactory());
        }
    
        @Bean
        public PlatformTransactionManager targetTransactionManager() {
            return new JpaTransactionManager(targetEntityManagerFactory());
        }
    
        private EntityManagerFactory createEntityManagerFactory(final String persistenceUnitName,
                final String databaseUrl) {
            final LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
    
            final DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl, username, password);
            dataSource.setDriverClassName(driverClassName);
            entityManagerFactory.setDataSource(dataSource);
    
            entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter);
            entityManagerFactory.setPackagesToScan("com.example.model");
            entityManagerFactory.setPersistenceUnitName(persistenceUnitName);
    
            final Properties properties = new Properties();
            properties.setProperty("hibernate.dialect", dialect);
            properties.setProperty("hibernate.hbm2ddl.auto", ddlAuto);
            entityManagerFactory.setJpaProperties(properties);
    
            entityManagerFactory.afterPropertiesSet();
            return entityManagerFactory.getObject();
        }
    
    }
    

    これで、さまざまなエンティティマネージャーを使用して、あるデータソースから別のデータソースにデータを簡単に読み書きできます。ここに小さなテストケースがあることを示すには:

    import static org.hamcrest.CoreMatchers.notNullValue;
    import static org.hamcrest.CoreMatchers.nullValue;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    import org.hibernate.ReplicationMode;
    import org.hibernate.Session;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.example.model.StorageEntry;
    
    @SpringBootTest
    @RunWith(SpringRunner.class)
    @Transactional(transactionManager = "targetTransactionManager")
    public class ReplicationTests {
    
        @PersistenceContext(unitName = "source")
        private EntityManager sourceEntityManager;
    
        @PersistenceContext(unitName = "target")
        private EntityManager targetEntityManager;
    
        @Test
        public void copyEntityBetweenPersistenceUnits() {
            final StorageEntry entityToCopy = new StorageEntry();
            entityToCopy.setSomeValue("copyMe!");
            sourceEntityManager.persist(entityToCopy);
    
            final Long id = entityToCopy.getId();
    
            final StorageEntry sourceEntity = sourceEntityManager.find(StorageEntry.class, id);
            assertThat("Entity should exist in default schema!", sourceEntity, notNullValue());
    
            StorageEntry targetEntity = targetEntityManager.find(StorageEntry.class, id);
            assertThat("Target schema should not contain the entity, yet!", targetEntity, nullValue());
    
            final Session hibernateSession = targetEntityManager.unwrap(Session.class);
            hibernateSession.replicate(sourceEntity, ReplicationMode.OVERWRITE);
    
            targetEntityManager.flush();
            targetEntityManager.clear();
    
            targetEntity = targetEntityManager.find(StorageEntry.class, id);
            assertThat("Entity should be copied now!", targetEntity, notNullValue());
        }
    
    }
    

    最後に、のいずれかを選択します。可能なレプリケーションモード ニーズに合っています。

    それで全部です。トランザクションを使用することもできます。両方の永続性ユニットのいずれかを決定し、テストが@Transactional(transactionManager = "targetTransactionManager")で行うように、そのトランザクションマネージャーを活用します。 。



    1. MariaDBでのDATEDIFF()のしくみ

    2. perlDBIfetchrow_hashrefの高速化

    3. 12cデータ編集

    4. Access2016でフォームヘッダーの背景色を変更する方法