sql >> Database >  >> RDS >> Mysql

Gegevens kopiëren tussen verschillende databases (beide worden ondersteund door jdbc)

Natuurlijk is het op een heel gemakkelijke manier mogelijk als de schema's hetzelfde zijn. En aangezien u beide databases met dezelfde Hibernate-toewijzing hebt gemaakt, moeten ze gelijk zijn in de Entity zin.

U hebt slechts twee Hibernate-persistentie-eenheden (gegevensbronnen) nodig. Als beide correct zijn geconfigureerd en u de specifieke EntityManager . hebt instanties handig, ga gewoon naar de Hibernate Session niveau - voor zover ik weet ondersteunt JPA dat niet op deze manier (corrigeer me als ik het mis heb) - en repliceer uw bronentiteit naar uw doeldatabase.

Omdat ik graag met Spring werk, zal ik Spring Boot gebruiken voor het volgende voorbeeld. Behalve de configuratie zou de replicatiestap hetzelfde worden geïmplementeerd met elke Hibernate-toepassing.

Ik gebruik ook twee PostgreSQL-databases in plaats van een HSQLB, alleen om het simpel te houden. Breid gewoon het configuratiegedeelte uit als uw configuraties uit elkaar drijven, het enige verschil tussen mijn persistentie-eenheden is de gegevensbron-URL.

Dus eerst hebben we een entiteit nodig om de replicatie te testen:

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

}

Dit is (de YAML-versie van) de configuratie van de twee gegevensbronnen (zie de tweede gegevensbron-url genaamd targetDatabaseUrl ), Alle andere delen van de configuratie worden gebruikt voor beide persistentie-eenheden:

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

Het volgende deel is de configuratieklasse voor de gegevensbronnen:

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();
    }

}

Nu kunt u de verschillende entiteitsmanagers gebruiken om eenvoudig uw gegevens van de ene gegevensbron naar de andere te lezen en te schrijven. Om dat te laten zien is hier een kleine testcase:

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());
    }

}

Kies ten slotte een van de mogelijke replicatiemodi die bij uw behoeften past.

Dat is alles. U kunt zelfs een transactie gebruiken, kies gewoon voor een van beide persistentie-eenheden en maak gebruik van de transactiemanager zoals de test doet met @Transactional(transactionManager = "targetTransactionManager") .



  1. .NET Core 2.1 Identity krijgt alle gebruikers met hun bijbehorende rollen

  2. Taal wijzigen van systeem- en foutmeldingen in PostgreSQL

  3. PHP gebruiken om afbeeldingen naar een map te uploaden terwijl beschrijvingen in een database worden opgeslagen

  4. Verbinding kan niet worden gecast naar oracle.jdbc.OracleConnection