Spring Batch Tutorial:Schreiben von Informationen in eine Datenbank mit JDBC
Mein Spring Batch-Tutorial hat uns beigebracht, die Eingabedaten unseres Batch-Jobs aus verschiedenen Datenquellen zu lesen. Unsere Batch-Jobs sind jedoch nicht sehr nützlich, da wir nicht wissen, wie wir die Daten speichern können, die aus diesen Datenquellen gelesen werden.
Es ist an der Zeit, den nächsten Schritt zu tun und zu erfahren, wie wir die Daten speichern können, die von unserem Spring Batch-Job verarbeitet wurden. Dieser Blogbeitrag hilft uns, die verarbeiteten Daten mithilfe von JDBC in eine Datenbank zu schreiben.
Beginnen wir mit einem kurzen Blick auf unsere Beispielanwendung.
Einführung in unsere Beispielanwendung
Während dieses Tutorials werden wir mehrere Spring Batch-Jobs implementieren, die die Studenteninformationen eines Online-Kurses verarbeiten. Die Informationen eines einzelnen Schülers bestehen aus den folgenden Informationen:
- Der Name des Schülers.
- Die E-Mail-Adresse des Kursteilnehmers.
- Der Name des gekauften Pakets.
Bevor wir diese Informationen in eine Datenbank schreiben können, müssen wir die Eingabedaten für die Komponente bereitstellen, die sie in eine Datenbank schreibt. In diesem Fall werden diese Informationen mithilfe von StudentDTO bereitgestellt Objekte.
Das StudentDTO Klasse enthält die Informationen eines einzelnen Schülers und ihr Quellcode sieht wie folgt aus:
public class StudentDTO { private String emailAddress; private String name; private String purchasedPackage; public StudentDTO() {} public String getEmailAddress() { return emailAddress; } public String getName() { return name; } public String getPurchasedPackage() { return purchasedPackage; } public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } public void setName(String name) { this.name = name; } public void setPurchasedPackage(String purchasedPackage) { this.purchasedPackage = purchasedPackage; } }
Lassen Sie uns weitermachen und herausfinden, wie wir den Anwendungskontext unserer Anwendung konfigurieren können.
Konfigurieren des Anwendungskontextes unserer Anwendung
Bevor wir den ItemWriter
Zuerst , wenn wir Spring Framework verwenden, müssen wir diesen Schritten folgen:
- Fügen Sie ein jdbcTemplate() hinzu -Methode in die Anwendungskontext-Konfigurationsklasse.
- Stellen Sie sicher, dass die jdbcTemplate() -Methode gibt ein NamedParameterJdbcTemplate zurück Objekt und nimmt eine DataSource Objekt als Methodenparameter.
- Kommentieren Sie die Methode mit @Bean Anmerkung.
- Implementieren Sie die Methode, indem Sie ein neues NamedParameterJdbcTemplate zurückgeben Objekt.
Der relevante Teil unserer Anwendungskontext-Konfigurationsklasse sieht wie folgt aus:
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); } }
Zweiter , wenn wir Spring Boot verwenden und die automatische Konfigurationsfunktion nicht deaktiviert haben, müssen wir keine Änderungen an unserer Konfiguration vornehmen, da Spring Boot sowohl das JdbcTemplate konfiguriert und NamedParameterJdbcTemplate Bohnen.
Fahren wir fort und konfigurieren den ItemWriter
Schreiben von Informationen in eine Datenbank mit JDBC
Wir können den ItemWriter
Zuerst , müssen wir die Konfigurationsklasse erstellen, die die Beans enthält, die den Workflow unseres Spring Batch-Jobs beschreiben. Wir können dies tun, indem wir eine CsvFileToDatabaseJobConfig erstellen Klasse und kommentieren Sie sie mit @Configuration Anmerkung.
Der Quellcode der CsvFileToDatabaseJobConfig Klasse sieht wie folgt aus:
import org.springframework.context.annotation.Configuration; @Configuration public class CsvFileToDatabaseJobConfig { }
Zweiter , müssen wir die Methode erstellen, die unseren ItemWriter konfiguriert Bohne. Wir können dies tun, indem wir diesen Schritten folgen:
- Fügen Sie eine neue Methode zu unserer Anwendungskontext-Konfigurationsklasse hinzu und stellen Sie sicher, dass die erstellte Methode ein ItemWriter
zurückgibt Objekt. - Stellen Sie sicher, dass die erstellte Methode die DataSource übernimmt und NamedParameterJdbcTemplate Objekte als Methodenparameter.
- Implementieren Sie die Methode, indem Sie null zurückgeben .
Nachdem wir der CsvFileToDatabaseJobConfig eine neue Methode hinzugefügt haben Klasse sieht der Quellcode wie folgt aus:
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; } }
Dritter , müssen wir einen neuen JdbcBatchItemWriter
Nachdem wir dies getan haben, ist der Quellcode der CsvFileToDatabaseJobConfig Klasse sieht wie folgt aus:
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; } }
Unser nächster Schritt ist die Konfiguration von INSERT Anweisung, die Studenteninformationen in unsere Datenbank einfügt. Wir können zwei verschiedene Strategien verwenden, um die Parameter unseres INSERT anzugeben -Anweisung, und beide Strategien erfordern eine etwas andere Konfiguration.
Beginnen wir mit der Erstellung eines INSERT Anweisung, die indizierte Parameter verwendet.
Indizierte Parameter verwenden
Wenn wir indizierte Parameter verwenden möchten, können wir das verwendete INSERT konfigurieren -Anweisung, indem Sie diesen Schritten folgen:
Zuerst , müssen wir ein INSERT erstellen -Anweisung, die Daten in die Studenten einfügt Tabelle und verwendet indizierte Parameter.
Nachdem wir ein konstantes Feld erstellt haben, das unser neues INSERT enthält -Anweisung und stellte sicher, dass der JdbcBatchItemWriter Objekt verwendet unser neues INSERT -Anweisung, der Quellcode der CsvFileToDatabaseJobConfig Klasse sieht wie folgt aus:
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; } }
Zweiter , müssen wir eine Klasse erstellen, die den ItemPreparedStatementSetter
Wir können diese Klasse erstellen, indem wir diesen Schritten folgen:
- Erstellen Sie eine Klasse, die den ItemPreparedStatementSetter
implementiert Schnittstelle. Wenn wir diese Schnittstelle implementieren, müssen wir einen Typparameter angeben, der den Typ des Elements angibt (StudentDTO ), die die eigentlichen Parameterwerte enthält. - Implementieren Sie setValues() -Methode und konfigurieren Sie die Parameterwerte in dieser Reihenfolge:emailAddress , Name und gekauftes Paket .
Der Quellcode der erstellten Klasse sieht wie folgt aus:
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()); } }
Dritter , müssen wir sicherstellen, dass der JdbcBatchItemWriter verwendet den StudentPreparedStatementSetter Klasse, wenn sie die tatsächlichen Parameterwerte des aufgerufenen INSERT ermittelt Aussage.
Nachdem wir den verwendeten ItemPreparedStatementSetter konfiguriert haben Objekt, der Quellcode der CsvFileToDatabaseJobConfig Klasse sieht wie folgt aus:
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; } }
Wir haben jetzt einen ItemWriter konfiguriert Bean, das Informationen in unsere Datenbank einfügt, indem es ein INSERT verwendet -Anweisung, die indizierte Parameter verwendet.
Lassen Sie uns herausfinden, wie wir dasselbe Ergebnis mit INSERT erreichen können Anweisung, die benannte Parameter verwendet.
Verwenden von benannten Parametern
Wenn wir benannte Parameter verwenden möchten, können wir das verwendete INSERT konfigurieren -Anweisung, indem Sie diesen Schritten folgen:
Zuerst , müssen wir ein INSERT erstellen -Anweisung, die Daten in die Studenten einfügt Tabelle und verwendet benannte Parameter. Wenn wir die Namen unserer benannten Parameter angeben, sollten wir Parameternamen verwenden, die den Eigenschaftsnamen des StudentDTO entsprechen Klasse.
Nachdem wir ein konstantes Feld erstellt haben, das unser neues INSERT enthält -Anweisung und stellte sicher, dass der JdbcBatchItemWriter Objekt verwendet unser neues INSERT -Anweisung, der Quellcode der CsvFileToDatabaseJobConfig Klasse sieht wie folgt aus:
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; } }
Zweiter , müssen wir den verwendeten ItemSqlParameterSourceProvider
Weil die Namen unserer benannten Parameter gleich den Eigenschaftsnamen des StudentDTO sind Klasse können wir den BeanPropertyItemSqlParameterSourceProvider verwenden Klasse dazu.
Nachdem wir den verwendeten ItemSqlParameterSourceProvider
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; } }
Wir haben jetzt einen ItemWriter konfiguriert Bean, das Informationen in unsere Datenbank einfügt, indem es ein INSERT verwendet Anweisung, die benannte Parameter verwendet.
Fassen wir zusammen, was wir aus dieser Lektion gelernt haben.
Zusammenfassung
Dieser Blogbeitrag hat uns vier Dinge gelehrt:
- Wir können Informationen in eine Datenbank schreiben, indem wir den JdbcBatchItemWriter
verwenden Klasse. - Wenn wir indizierte Parameter verwenden möchten, können wir die tatsächlichen Parameterwerte für JdbcBatchItemWriter
bereitstellen durch Implementieren eines ItemPreparedStatementSetter Schnittstelle. - Wenn wir benannte Parameter verwenden möchten, können wir die tatsächlichen Parameterwerte für JdbcBatchItemWriter
bereitstellen durch Implementieren eines ItemSqlParameterSourceProvider Schnittstelle. - Wenn wir benannte Parameter verwenden und unsere Parameternamen den Eigenschaftsnamen der Klasse entsprechen, die die tatsächlichen Parameterwerte enthält, können wir die tatsächlichen Parameterwerte für JdbcBatchItemWriter
bereitstellen mithilfe von BeanPropertyItemSqlParameterSourceProvider Klasse.
P.S. Sie können die Beispielanwendungen dieses Blogposts von Github abrufen:Spring example und Spring Boot example.