Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Sao chép dữ liệu giữa các cơ sở dữ liệu khác nhau (cả hai đều được hỗ trợ jdbc)

Chắc chắn, có thể thực hiện một cách rất dễ dàng nếu các schemata giống nhau. Và vì bạn đã tạo cả hai cơ sở dữ liệu với cùng một ánh xạ Hibernate nên chúng phải bằng nhau trong Entity giác quan.

Bạn chỉ cần hai đơn vị liên tục Hibernate (nguồn dữ liệu). Nếu cả hai đều được định cấu hình đúng cách và bạn có EntityManager cụ thể các trường hợp hữu ích, chỉ cần đi xuống Session Hibernate cấp độ - theo như tôi biết JPA không hỗ trợ điều đó theo cách này (hãy sửa cho tôi nếu tôi sai) - và sao chép thực thể nguồn của bạn vào cơ sở dữ liệu mục tiêu của bạn.

Vì tôi thích làm việc với Spring, tôi sẽ sử dụng Spring Boot cho ví dụ sau. Ngoại trừ cấu hình, bước sao chép sẽ được thực hiện giống như vậy với bất kỳ ứng dụng Hibernate nào.

Tôi cũng đang sử dụng hai cơ sở dữ liệu PostgreSQL thay vì HSQLB chỉ để giữ cho nó đơn giản. Chỉ cần mở rộng phần cấu hình nếu cấu hình của bạn khác nhau, điểm khác biệt duy nhất giữa các đơn vị độ bền của tôi là url nguồn dữ liệu.

Vì vậy, trước tiên chúng ta cần một thực thể để kiểm tra bản sao:

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

}

Đây là (phiên bản YAML của) cấu hình của hai nguồn dữ liệu (xem url nguồn dữ liệu thứ hai được gọi là targetDatabaseUrl ), Tất cả các phần khác của cấu hình sẽ được sử dụng cho cả hai đơn vị duy trì:

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

Phần tiếp theo là lớp cấu hình cho các nguồn dữ liệu:

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

}

Giờ đây, bạn có thể sử dụng các trình quản lý thực thể khác nhau để chỉ cần đọc và ghi dữ liệu của mình từ nguồn dữ liệu này sang nguồn dữ liệu khác. Để cho thấy điều đó, đây là một trường hợp thử nghiệm nhỏ:

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

}

Cuối cùng, chọn một trong các các chế độ sao chép có thể có phù hợp với nhu cầu của bạn.

Đó là tất cả. Bạn thậm chí có thể sử dụng một giao dịch, chỉ cần quyết định cho một trong cả hai đơn vị bền vững và tận dụng trình quản lý giao dịch của nó giống như thử nghiệm với @Transactional(transactionManager = "targetTransactionManager") .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tối ưu hóa Nhập MySQL (Chuyển đổi một Dump SQL dài dòng thành một Speedy One / sử dụng các phần chèn mở rộng)

  2. Làm thế nào để làm cho MEMORY ENGINE mysql lưu trữ nhiều dữ liệu hơn?

  3. lỗi trong cú pháp SQL của bạn .. gần 'key'

  4. Làm cách nào để phân trang kết quả truy vấn cho Infinite Scroll?

  5. làm thế nào để kiểm tra xem truy vấn mysql trả về không có kết quả (không tìm thấy bản ghi) bằng php?