Spring Batch 写数据库教程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/neweastsun/article/details/101980066

Spring Batch 写数据库教程

上文我们学习如何读数据库,本文我们看如何通过Spring Batch写数据库。

1.需求及环境准备

1.1. 示例需求说明

需要实现把在线学习系统中的学生信息通过Srping job写入数据库,单个学生信息类如下:学生姓名、电子邮件、已购学习包。写数据库之前,我们需要提供输入数据组件。本例我们使用StudentDto对象,其包括单个学生信息:

@Data
public class StudentDTO {
 
    private String emailAddress;
    private String name;
    private String purchasedPackage;
}

下面开始配置应用上下文。

1.2. 配置应用上下文

在配置写数据库ItemWriter对象之前,需要先配置ItemWriter bean,有两种方式:

1)、如果使用Spring Framework,需要下列几个步骤:

  • 在应用上下文配置类中增加jdbcTemplate() 方法.

  • 确保jdbcTemplate() 方法返回 NamedParameterJdbcTemplate 对象并带有DataSource对象作为参数.

  • 在方法上增加@Bean 注解.

  • 实现方法并返回NamedParameterJdbcTemplate 对象.

部分对面如下:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
import javax.sql.DataSource;
import java.util.Properties;
 
@Configuration
public class PersistenceContext {
 
    @Bean(destroyMethod = "close")
    DataSource dataSource(Environment env) {
        HikariConfig dataSourceConfig = new HikariConfig();
 
        dataSourceConfig.setDriverClassName(env.getRequiredProperty("db.driver"));
        dataSourceConfig.setJdbcUrl(env.getRequiredProperty("db.url"));
        dataSourceConfig.setUsername(env.getRequiredProperty("db.username"));
        dataSourceConfig.setPassword(env.getRequiredProperty("db.password"));
 
        return new HikariDataSource(dataSourceConfig);
    }
     
    @Bean
    NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new NamedParameterJdbcTemplate(dataSource);
    }
}

2)、如果使用Spring Boot,而且还没有禁用它的自动配置特性,那么我们就不必对配置进行任何更改,因为Spring Boot同时配置了JdbcTemplate和NamedParameterJdbcTemplate bean。

下面继续配置ItemWriter,负责写信息入库。

2. 通过jdbc写数据库

通过下面几个步骤配置ItemWriter:

第一步创建配置类,其中包括Spring job流程描述。创建CsvFileToDatabaseJobConfig 类并增加注解 @Configuration。对应代码如下:

import org.springframework.context.annotation.Configuration;
 
@Configuration
public class CsvFileToDatabaseJobConfig {
 
}

第二步创建方法配置ItemWriter bean,通过下面几步实现:

  • 在配置类中增加方法,确保方法返回ItemWriter 对象.

  • 确保方法带有 DataSource 和 NamedParameterJdbcTemplate 对象作为参数.

  • 暂时通过返回null实现方法.

增加方法后CsvFileToDatabaseJobConfig类代码如下:

import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
import javax.sql.DataSource;
 
@Configuration
public class CsvFileToDatabaseJobConfig {
     
    @Bean
    ItemWriter<StudentDTO> csvFileDatabaseItemWriter(DataSource dataSource, 
                                                     NamedParameterJdbcTemplate jdbcTemplate) {
        return null;
    }
}

第三步创建JdbcBatchItemWriter对象,设置数据源和jdbcTemplate,确保方法返回该对象。最终CsvFileToDatabaseJobConfig类csvFileDatabaseItemWriter方法的完整代码如下:

import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
import javax.sql.DataSource;
 
@Configuration
public class CsvFileToDatabaseJobConfig {
 
    @Bean
    ItemWriter<StudentDTO> csvFileDatabaseItemWriter(DataSource dataSource, 
                                                     NamedParameterJdbcTemplate jdbcTemplate) {
        JdbcBatchItemWriter<StudentDTO> databaseItemWriter = new JdbcBatchItemWriter<>();
        databaseItemWriter.setDataSource(dataSource);
        databaseItemWriter.setJdbcTemplate(jdbcTemplate);
         
        return databaseItemWriter;
    }
}

下面配置插入数据库的INSERT语句。可以使用两者策略制定INSERT语句的参数,两者配置有差异。下面首先看看索引参数。

2.1. 索引参数

索引参数配置包括下面几步:

第一步创建出入student表的INSERT语句,使用常量属性保存INSERT语句并确保JdbcBatchItemWriter 对象使用该常量,CsvFileToDatabaseJobConfig代码如下:

import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
import javax.sql.DataSource;
 
@Configuration
public class CsvFileToDatabaseJobConfig {
 
    private static final String QUERY_INSERT_STUDENT = "INSERT " +
            "INTO students(email_address, name, purchased_package) " +
            "VALUES (?, ?, ?)";
 
    @Bean
    ItemWriter<StudentDTO> csvFileDatabaseItemWriter(DataSource dataSource,
                                                     NamedParameterJdbcTemplate jdbcTemplate) {
        JdbcBatchItemWriter<StudentDTO> databaseItemWriter = new JdbcBatchItemWriter<>();
        databaseItemWriter.setDataSource(dataSource);
        databaseItemWriter.setJdbcTemplate(jdbcTemplate);
 
        databaseItemWriter.setSql(QUERY_INSERT_STUDENT);
 
        return databaseItemWriter;
    }
}

第二步创建实现 ItemPreparedStatementSetter接口的类,该类负责给PreparedStatement 对象设置实际参数值,通过实现setValues方法实现。主要包括下面两步:

  • 创建实现ItemPreparedStatementSetter接口的类,并设置T类型为StudentDTO。
  • 实现setValues方法并按顺序配置参数值: emailAddress, name, purchasedPackage.

完整代码如下:

import org.springframework.batch.item.database.ItemPreparedStatementSetter;
 
import java.sql.PreparedStatement;
import java.sql.SQLException;
 
final class StudentPreparedStatementSetter implements ItemPreparedStatementSetter<StudentDTO> {
 
    @Override
    public void setValues(StudentDTO student, 
                          PreparedStatement preparedStatement) throws SQLException {
        preparedStatement.setString(1, student.getEmailAddress());
        preparedStatement.setString(2, student.getName());
        preparedStatement.setString(3, student.getPurchasedPackage());
    }
}

第三步确保JdbcBatchItemWriter 使用StudentPreparedStatementSetter。确保在执行INSERT语句时实际参数值被正确设置。
正确配置ItemPreparedStatementSetter 对象后,配置类的CsvFileToDatabaseJobConfig代码如下:

import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.ItemPreparedStatementSetter;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
import javax.sql.DataSource;
 
@Configuration
public class CsvFileToDatabaseJobConfig {
 
    private static final String QUERY_INSERT_STUDENT = "INSERT " +
            "INTO students(email_address, name, purchased_package) " +
            "VALUES (?, ?, ?)";
 
    @Bean
    ItemWriter<StudentDTO> csvFileDatabaseItemWriter(DataSource dataSource,
                                                     NamedParameterJdbcTemplate jdbcTemplate) {
        JdbcBatchItemWriter<StudentDTO> databaseItemWriter = new JdbcBatchItemWriter<>();
        databaseItemWriter.setDataSource(dataSource);
        databaseItemWriter.setJdbcTemplate(jdbcTemplate);
 
        databaseItemWriter.setSql(QUERY_INSERT_STUDENT);
 
        ItemPreparedStatementSetter<StudentDTO> valueSetter = 
                new StudentPreparedStatementSetter();
        databaseItemWriter.setItemPreparedStatementSetter(valueSetter);
 
        return databaseItemWriter;
    }
}

通过上面几步就完成了ItemWriter 的配置,通过INSERT语句和索引参数实现在数据库中插入信息。

2.2. 命名参数

使用命名需要下面几个步骤进行配置:

第一步使用命名参数创建插入表的INSERT语句。使用命名参数的名称应该和StudentDto类属性名称保持一致。然后定义常量保存INSERT语句并确保JdbcBatchItemWriter 使用该常量,请看CsvFileToDatabaseJobConfig配置代码:

import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
import javax.sql.DataSource;
 
@Configuration
public class CsvFileToDatabaseJobConfig {
     
    private static final String QUERY_INSERT_STUDENT = "INSERT " +
            "INTO students(email_address, name, purchased_package) " +
            "VALUES (:emailAddress, :name, :purchasedPackage)";
     
    @Bean
    ItemWriter<StudentDTO> csvFileDatabaseItemWriter(DataSource dataSource, 
                                                     NamedParameterJdbcTemplate jdbcTemplate) {
        JdbcBatchItemWriter<StudentDTO> databaseItemWriter = new JdbcBatchItemWriter<>();
        databaseItemWriter.setDataSource(dataSource);
        databaseItemWriter.setJdbcTemplate(jdbcTemplate);
 
        databaseItemWriter.setSql(QUERY_INSERT_STUDENT);
 
        return databaseItemWriter;
    }
}

第二步配置ItemSqlParameterSourceProvider 对象,JdbcBatchItemWriter 对象使用该对象获得SqlParameterSource 对象引用,用于获取命名参数的值。

因为命名参数名称与StudentDTO名称一致,可以直接使用BeanPropertyItemSqlParameterSourceProvider 类实现。
配置完使用ItemSqlParameterSourceProvider 对象后,CsvFileToDatabaseJobConfig代码如下:

import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.ItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 
import javax.sql.DataSource;
 
@Configuration
public class CsvFileToDatabaseJobConfig {
     
    private static final String QUERY_INSERT_STUDENT = "INSERT " +
            "INTO students(email_address, name, purchased_package) " +
            "VALUES (:emailAddress, :name, :purchasedPackage)";
     
    @Bean
    ItemWriter<StudentDTO> csvFileDatabaseItemWriter(DataSource dataSource, 
                                                     NamedParameterJdbcTemplate jdbcTemplate) {
        JdbcBatchItemWriter<StudentDTO> databaseItemWriter = new JdbcBatchItemWriter<>();
        databaseItemWriter.setDataSource(dataSource);
        databaseItemWriter.setJdbcTemplate(jdbcTemplate);
 
        databaseItemWriter.setSql(QUERY_INSERT_STUDENT);
 
        ItemSqlParameterSourceProvider<StudentDTO> paramProvider = 
                new BeanPropertyItemSqlParameterSourceProvider<>();
        databaseItemWriter.setItemSqlParameterSourceProvider(paramProvider);
 
        return databaseItemWriter;
    }
}

这就完成了命名参数方式配置。

3.总结

本文介绍了Spring batch写数据库,通过创建JdbcBatchItemWriter类。如果使用索引参数需要 ItemPreparedStatementSetter 接口,而使用命名参数需要实现ItemSqlParameterSourceProvider接口。如果使用命名参数且名称与DTO属性名称相同可以使用 BeanPropertyItemSqlParameterSourceProvider类。

猜你喜欢

转载自blog.csdn.net/neweastsun/article/details/101980066