【问题标题】:Data Migration from One Db to another using Spring batch and Spring boot使用 Spring Batch 和 Spring Boot 将数据从一个 Db 迁移到另一个 Db
【发布时间】:2020-06-30 11:11:17
【问题描述】:

我是 Spring 框架的新手,我想使用 Spring boot n Batch 将数据从一个数据库迁移到另一个数据库

我正在尝试使用项目阅读器从 Mysql 数据库中读取数据,并使用相同作业的项目写入器将其写入 Oracle 数据库。

我能够从 Mysql db 中读取数据,但无法将其写入 Oracle Db,因为作者正在尝试将其写入 Mysql Db 本身。

我不确定为什么连接没有切换到 Oracle db。

请帮我看看我做错了什么。

应用程序属性

server.port=8082

spring.batch.job.enabled= false

spring.datasource.url = jdbc:mysql://localhost:3306/projectdb1
spring.datasource.username = root
spring.datasource.password = Mech_2015
spring.datasource.driverClassName = com.mysql.jdbc.Driver


#second db2 ...
db2.datasource.url = jdbc:oracle:thin:@localhost:1521:xe 
db2.datasource.username = system
db2.datasource.password = Mech_2015
db2.datasource.driverClassName = oracle.jdbc.driver.OracleDriver

实体经理

package com.techprimers.springbatchexample1.entity.manger;
@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "radiusEntityManager", transactionManagerRef = "radiusTransactionManager", basePackages = "com.techprimers.springbatchexample1.repository.userrepo")
public class RadiusConfig {

    private final PersistenceUnitManager persistenceUnitManager;

    public RadiusConfig(ObjectProvider<PersistenceUnitManager> persistenceUnitManager) {
        this.persistenceUnitManager = persistenceUnitManager.getIfAvailable();
    }

    @Bean
    @ConfigurationProperties("spring.jpa")
    public JpaProperties radiusJpaProperties() {
        return new JpaProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties radiusDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.properties")
    public DataSource radiusDataSource() {
        return (DataSource) radiusDataSourceProperties().initializeDataSourceBuilder().type(DataSource.class).build();
    }

    @Bean(name = "radiusEntityManager")
    public LocalContainerEntityManagerFactoryBean radiusEntityManager(JpaProperties radiusJpaProperties) {
        EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(radiusJpaProperties);
        return builder.dataSource(radiusDataSource()).packages(User.class).persistenceUnit("userDs").build();
    }

    @Bean
    public JpaTransactionManager radiusTransactionManager(EntityManagerFactory radiusEntityManager) {
        return new JpaTransactionManager(radiusEntityManager);
    }

    private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties radiusJpaProperties) {
        JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(radiusJpaProperties);
        return new EntityManagerFactoryBuilder(jpaVendorAdapter, radiusJpaProperties.getProperties(),
                this.persistenceUnitManager);
    }

    private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
        AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(jpaProperties.isShowSql());
        adapter.setDatabase(jpaProperties.getDatabase());
        adapter.setDatabasePlatform(jpaProperties.getDatabasePlatform());
        adapter.setGenerateDdl(jpaProperties.isGenerateDdl());
        return adapter;
    }

}

package com.techprimers.springbatchexample1.entity.manger;

@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "esbEntityManager", transactionManagerRef = "esbDetailsTransactionManager", basePackages = "com.techprimers.springbatchexample1.repository.userdetails")
public class EsbConfig {

    private final PersistenceUnitManager persistenceUnitManager;

    public EsbConfig(ObjectProvider<PersistenceUnitManager> persistenceUnitManager) {
        this.persistenceUnitManager = persistenceUnitManager.getIfAvailable();
    }

    @Bean
    @ConfigurationProperties("db2.jpa")
    public JpaProperties esbJpaProperties() {
        return new JpaProperties();
    }

    @Bean
    @ConfigurationProperties("db2.datasource")
    public DataSourceProperties esbDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "db2.datasource.properties")
    public DataSource esbDataSource() {
        return (DataSource) esbDataSourceProperties().initializeDataSourceBuilder().type(DataSource.class).build();
    }

    @Bean(name = "esbEntityManager")
    public LocalContainerEntityManagerFactoryBean esbEntityManager(JpaProperties esbJpaProperties) {
        EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(esbJpaProperties);
        return builder.dataSource(esbDataSource()).packages(UserDetails.class).persistenceUnit("userDetailDs").build();
    }

    @Bean
    public JpaTransactionManager esbTransactionManager(EntityManagerFactory esbEntityManager) {
        return new JpaTransactionManager(esbEntityManager);
    }

    private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties esbJpaProperties) {
        JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(esbJpaProperties);
        return new EntityManagerFactoryBuilder(jpaVendorAdapter, esbJpaProperties.getProperties(),
                this.persistenceUnitManager);
    }

    private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
        AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(jpaProperties.isShowSql());
        adapter.setDatabase(jpaProperties.getDatabase());
        adapter.setDatabasePlatform(jpaProperties.getDatabasePlatform());
        adapter.setGenerateDdl(jpaProperties.isGenerateDdl());
        return adapter;
    }

}

批量配置

package com.techprimers.springbatchexample1.config;

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringBatchConfig.class);


    @Bean
    @Primary
    @Qualifier("radiusDatasource")
    @ConfigurationProperties(prefix = "spring.datasource")
    DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "db2.datasource")
    @Qualifier("esbDatasource")
    DataSource oracleDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public InspectionProcessor processor() {
        return new InspectionProcessor();
    }

    @Bean
    public JdbcCursorItemReader<User> reader() {
        JdbcCursorItemReader<User> cursorItemReader = new JdbcCursorItemReader<>();
        cursorItemReader.setDataSource(mysqlDataSource());
        cursorItemReader.setSql("SELECT ID,CNAME,SID,CREATEDDATE,COMPLETEDDATE FROM INSPECTION");
        cursorItemReader.setRowMapper(new InspectionDetailRowmapper());
        return cursorItemReader;
    }

    private static final String QUERY_INSERT_STUDENT = "INSERT "
            + "INTO inspect(id,cname,completeddate,createddate,lastupdateddate,sid) " + "VALUES (?,?,?,?,?,?)";

    @Bean
    ItemWriter<UserDetails> databaseItemWriter(DataSource dataSource, NamedParameterJdbcTemplate jdbcTemplate) {

        LOGGER.info("Starting writer");

        JdbcBatchItemWriter<UserDetails> databaseItemWriter = new JdbcBatchItemWriter<>();
        databaseItemWriter.setDataSource(oracleDataSource());
        databaseItemWriter.setJdbcTemplate(jdbcTemplate);

        LOGGER.info(" writer");

        databaseItemWriter.setSql(QUERY_INSERT_STUDENT)

        ItemPreparedStatementSetter<UserDetails> valueSetter = new UserDetailsPreparedStatementSetter();
        databaseItemWriter.setItemPreparedStatementSetter(valueSetter);


        return databaseItemWriter;
    }

    @Bean
    Step dataMigrationStep(ItemReader<User> reader, ItemProcessor<User, UserDetails> processor,
            ItemWriter<UserDetails> databsaeItemWriter, StepBuilderFactory stepBuilderFactory) {
        return stepBuilderFactory.get("dataMigrationStep").<User, UserDetails>chunk(5).reader(reader)
                .processor(processor).writer(databsaeItemWriter).build();
    }

    @Bean
    Job dataMigrationJob(JobBuilderFactory jobBuilderFactory, @Qualifier("dataMigrationStep") Step dataMigrationStep) {
        return jobBuilderFactory.get("csvFileToDatabaseJob").incrementer(new RunIdIncrementer()).flow(dataMigrationStep)
                .end().build();
    }

}

【问题讨论】:

    标签: spring-boot oracle11g spring-batch multiple-databases itemwriter


    【解决方案1】:

    您的编写器没有正确地注入数据​​库来写入您的数据

    这个

        @Bean
        ItemWriter<UserDetails> databaseItemWriter(DataSource dataSource, NamedParameterJdbcTemplate jdbcTemplate) 
    

    而不是

        @Bean
        ItemWriter<UserDetails> databaseItemWriter(@Qualifier("esbDatasource") DataSource dataSource, NamedParameterJdbcTemplate jdbcTemplate) 
    

    【讨论】:

    • 我确实尝试过该限定符注释,但出现以下错误
    • 在类路径资源 [com/techprimers/springbatchexample1/config/SpringBatchConfig.class] 中定义名称为 'databaseItemWriter' 的 bean 创建错误:通过方法 'databaseItemWriter' 参数 0 表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有“javax.sql.DataSource”类型的合格 bean 可用:预计至少有 1 个有资格作为自动装配候选者的 bean。依赖注解:{@org.springframework.beans.factory.annotation.Qualifier(value=esbDatasource)}
    • 尝试使用@Bean(name="myBeanName") 命名你的bean
    • 由于您使用@Primary 注释了您的mysql 数据源,因此它是您的作家中注入的一个。在此答案中添加限定符应该可以。
    猜你喜欢
    • 2017-06-21
    • 2019-08-12
    • 2023-03-25
    • 2015-07-02
    • 2020-12-31
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 2019-05-18
    相关资源
    最近更新 更多