Java >> Java Tutorial >  >> Tag >> Spring

Spring Batch Tutorial:Lesen von Informationen aus einer relationalen Datenbank

In den vorherigen Teilen meines Spring Batch-Tutorials wurde beschrieben, wie Sie Informationen aus CSV- und XML-Dateien lesen können. Dies sind definitiv nützliche Fähigkeiten, aber wenn Sie echte Batch-Jobs schreiben möchten, müssen Sie wissen, wie Sie die Eingabedaten eines Spring Batch-Jobs aus einer relationalen Datenbank lesen können.

Nachdem Sie diesen Blogbeitrag gelesen haben, werden Sie:

  • Kann die Eingabedaten Ihres Batch-Jobs mit einem Datenbank-Cursor lesen.
  • Verstehen Sie, wie Sie die Eingabedaten Ihres Batch-Jobs mithilfe von Paginierung lesen können.

Beginnen wir mit einem kurzen Blick auf die Beispielanwendung.

Einführung in die Beispielanwendung

In diesem Blogbeitrag lesen Sie die Eingabedaten Ihres Batch-Jobs aus einer relationalen Datenbank, die die Studenteninformationen eines Online-Kurses enthält. Die Studenteninformationen finden sich im students Tabelle mit den folgenden Spalten:

  • Die email_address Spalte enthält die E-Mail-Adresse des Schülers.
  • Die name Spalte enthält den Namen des Schülers.
  • Die purchased_package Spalte enthält den Namen des gekauften Pakets.

Die ItemReader der die Studentenliste aus einer relationalen Datenbank liest, muss StudentDTO zurückgeben Objekte, die in aufsteigender Reihenfolge sortiert werden, indem die E-Mail-Adresse des Schülers als Sortierkriterium verwendet wird. Die 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;
    }
}

Als nächstes erfahren Sie, wie Sie die Eingabedaten Ihres Batch-Jobs mit einem Datenbank-Cursor lesen können.

Lesen der Eingabedaten Ihres Batch-Jobs mit einem Datenbank-Cursor

Sie können die Eingabedaten für Ihren Batch-Job bereitstellen, indem Sie einen ItemReader konfigurieren Bohne. Da Sie die Schülerinformationen mithilfe eines Datenbankcursors aus einer relationalen Datenbank lesen müssen, müssen Sie diese Bean folgendermaßen konfigurieren:

Zuerst müssen Sie die Konfigurationsklasse erstellen, die die Beans enthält, die den Ablauf Ihres Batch-Jobs beschreiben. Der Quellcode Ihrer Konfigurationsklasse sieht wie folgt aus:

import org.springframework.context.annotation.Configuration;

@Configuration
public class DatabaseCursorExampleJobConfig {
}

Zweite müssen Sie eine Methode erstellen, die Ihren ItemReader konfiguriert Bohne. Diese Methode muss einen DataSource annehmen Objekt als Methodenparameter und geben einen ItemReader<StudentDTO> zurück Objekt. Nachdem Sie diese Methode erstellt haben, sieht der Quellcode Ihrer Konfigurationsklasse wie folgt aus:

import org.springframework.batch.item.ItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
 
@Configuration
public class DatabaseCursorExampleJobConfig {
 
    @Bean
    public ItemReader<StudentDTO> itemReader(DataSource dataSource) {
         
    }
}

Dritter , müssen Sie Ihre ItemReader konfigurieren Bean, indem Sie diesen Schritten folgen:

  1. Erstellen Sie einen neuen JdbcCursorItemReaderBuilder<StudentDTO> Objekt. Dieses Objekt bietet eine fließende API, mit der Sie einen neuen JdbcCursorItemReader<StudentDTO> erstellen können Objekt, das die Eingabedaten liest, indem es einen JDBC-Cursor öffnet und kontinuierlich die nächste Zeile aus ResultSet abruft .
  2. Konfigurieren Sie den Namen des erstellten JdbcCursorItemReader<StudentDTO> Objekt.
  3. Konfigurieren Sie die Datenquelle, die Datenbankverbindungen zum erstellten JdbcCursorItemReader<StudentDTO> bereitstellt Objekt.
  4. Konfigurieren Sie die SQL-Abfrage, die verwendet wird, um die Eingabedaten aus der verwendeten Datenbank abzufragen.
  5. Konfigurieren Sie den RowMapper<T> Objekt, das die Informationen einer einzelnen Datenbankzeile in einen neuen T umwandelt Objekt. Da die Feldnamen der StudentDTO Klasse stimmt mit den Spaltennamen von students überein Tabelle können Sie den verwendeten RowMapper konfigurieren indem Sie einen neuen BeanPropertyRowMapper<StudentDTO> erstellen Objekt.
  6. Gib den erstellten JdbcCursorItemReader<StudentDTO> zurück Objekt.

Nachdem Sie Ihren ItemReader konfiguriert haben Bean sieht der Quellcode Ihrer Konfigurationsklasse wie folgt aus:

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;

import javax.sql.DataSource;

@Configuration
public class DatabaseCursorExampleJobConfig {

    private static final String QUERY_FIND_STUDENTS =
            "SELECT " +
                    "email_address, " +
                    "name, " +
                    "purchased_package " +
            "FROM STUDENTS " +
            "ORDER BY email_address ASC";

    @Bean
    public ItemReader<StudentDTO> itemReader(DataSource dataSource) {
        return new JdbcCursorItemReaderBuilder<StudentDTO>()
                .name("cursorItemReader")
                .dataSource(dataSource)
                .sql(QUERY_FIND_STUDENTS)
                .rowMapper(new BeanPropertyRowMapper<>(StudentDTO.class))
                .build();
    }
}

Lassen Sie uns herausfinden, wie Sie die Eingabedaten Ihres Batch-Jobs mithilfe von Paginierung lesen können.

Lesen der Eingabedaten Ihres Batch-Jobs mithilfe von Paginierung

Sie können die Eingabedaten für Ihren Batch-Job bereitstellen, indem Sie einen ItemReader konfigurieren Bohne. Da Sie die Schülerinformationen mithilfe von Paginierung aus einer relationalen Datenbank lesen müssen, müssen Sie diese Bean folgendermaßen konfigurieren:

Zuerst müssen Sie die Konfigurationsklasse erstellen, die die Beans enthält, die den Ablauf Ihres Batch-Jobs beschreiben. Der Quellcode Ihrer Konfigurationsklasse sieht wie folgt aus:

import org.springframework.context.annotation.Configuration;

@Configuration
public class JDBCPaginationExampleJobConfig {
}

Zweite haben Sie eine Methode erstellt, die SqlPagingQueryProviderFactoryBean konfiguriert Bean und stellen Sie sicher, dass diese Methode DataSource akzeptiert Objekt als Methodenparameter. Der SqlPagingQueryProviderFactoryBean Klasse hat zwei Verantwortlichkeiten:

  • Die verwendete Datenbank wird automatisch erkannt.
  • Es bestimmt den passenden PagingQueryProvider Implementierung, die die SQL-Abfragen erstellt, die die paginierten Daten aus der Datenbank abrufen.

Nachdem Sie diese Methode erstellt haben, müssen Sie sie wie folgt implementieren:

  1. Erstellen Sie einen neuen SqlPagingQueryProviderFactoryBean Objekt.
  2. Konfigurieren Sie die Datenquelle, die verwendet wird, um den Typ der verwendeten Datenbank zu bestimmen.
  3. Geben Sie den SELECT an und FROM Klauseln, die alle Zeilen aus der Quelltabelle abfragen.
  4. Geben Sie die Sortierschlüssel an, die verwendet werden, um die Abfrageergebnisse der ausgeführten Datenbankabfragen zu sortieren.
  5. Gib den erstellten SqlPagingQueryProviderFactoryBean zurück Objekt.

Nachdem Sie den SqlPagingQueryProviderFactoryBean konfiguriert haben Bean sieht der Quellcode Ihrer Konfigurationsklasse wie folgt aus:

import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class JDBCPaginationExampleJobConfig {
    
    @Bean
    public SqlPagingQueryProviderFactoryBean queryProvider(DataSource dataSource) {
        SqlPagingQueryProviderFactoryBean provider = 
                new SqlPagingQueryProviderFactoryBean();

        provider.setDataSource(dataSource);
        provider.setSelectClause("SELECT email_address, name, purchased_package");
        provider.setFromClause("FROM students");
        provider.setSortKeys(sortByEmailAddressAsc());

        return provider;
    }

    private Map<String, Order> sortByEmailAddressAsc() {
        Map<String, Order> sortConfiguration = new HashMap<>();
        sortConfiguration.put("email_address", Order.ASCENDING);
        return sortConfiguration;
    }
}

Dritter müssen Sie eine Methode erstellen, die Ihren ItemReader konfiguriert Bohne. Diese Methode muss DataSource annehmen und PagingQueryProvider Objekte als Methodenparameter und muss einen ItemReader<StudentDTO> zurückgeben Objekt.

Nachdem Sie diese Methode erstellt haben, müssen Sie sie wie folgt implementieren:

  1. Erstellen Sie einen neuen JdbcPagingItemReaderBuilder<StudentDTO> Objekt. Dieses Objekt bietet eine fließende API, mit der Sie einen neuen JdbcPagingItemReader<StudentDTO> erstellen können Objekt, das die Eingabedaten Ihres Batch-Jobs Seite für Seite mit JDBC liest.
  2. Konfigurieren Sie den Namen des erstellten JdbcPagingItemReader<StudentDTO> Objekt.
  3. Konfigurieren Sie die Datenquelle, die Datenbankverbindungen zum erstellten JdbcPagingItemReader<StudentDTO> bereitstellt Objekt.
  4. Konfigurieren Sie die verwendete Seitengröße. Sie können eine als Seitengröße verwenden, da der students Tabelle hat nur drei Zeilen. Wenn es sich jedoch um eine reale Anwendung handelt, sollten Sie die beste Seitengröße auswählen, indem Sie ein Profil für Ihren Batch-Job erstellen.
  5. Konfigurieren Sie den verwendeten PagingQueryProvider Objekt. Wie Sie sich erinnern, erstellt dieses Objekt die SQL-Abfragen, die die paginierten Daten aus der Datenbank abrufen.
  6. Konfigurieren Sie den RowMapper<T> Objekt, das die Informationen einer einzelnen Datenbankzeile in einen neuen T umwandelt Objekt. Da die Feldnamen der StudentDTO Klasse stimmt mit den Spaltennamen des students überein Tabelle können Sie den verwendeten RowMapper konfigurieren indem Sie einen neuen BeanPropertyRowMapper<StudentDTO> erstellen Objekt.
  7. Gib den erstellten JdbcPagingItemReader<StudentDTO> zurück Objekt.

Nachdem Sie Ihren ItemReader konfiguriert haben Bean sieht der Quellcode Ihrer Konfigurationsklasse wie folgt aus:

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.PagingQueryProvider;
import org.springframework.batch.item.database.builder.JdbcPagingItemReaderBuilder;
import org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class JDBCPaginationExampleJobConfig {

    @Bean
    public ItemReader<StudentDTO> itemReader(DataSource dataSource,
                                             PagingQueryProvider queryProvider) {
        return new JdbcPagingItemReaderBuilder<StudentDTO>()
                .name("pagingItemReader")
                .dataSource(dataSource)
                .pageSize(1)
                .queryProvider(queryProvider)
                .rowMapper(new BeanPropertyRowMapper<>(StudentDTO.class))
                .build();
    }

    @Bean
    public SqlPagingQueryProviderFactoryBean queryProvider(DataSource dataSource) {
        SqlPagingQueryProviderFactoryBean provider =
                new SqlPagingQueryProviderFactoryBean();

        provider.setDataSource(dataSource);
        provider.setSelectClause("SELECT email_address, name, purchased_package");
        provider.setFromClause("FROM students");
        provider.setSortKeys(sortByEmailAddressAsc());

        return provider;
    }

    private Map<String, Order> sortByEmailAddressAsc() {
        Map<String, Order> sortConfiguration = new HashMap<>();
        sortConfiguration.put("email_address", Order.ASCENDING);
        return sortConfiguration;
    }
}
}

Sie können nun die Eingabedaten Ihres Batch-Jobs aus einer relationalen Datenbank auslesen. Fassen wir zusammen, was Sie aus diesem Blogbeitrag gelernt haben.

Zusammenfassung

Dieser Blogbeitrag hat Ihnen drei Dinge beigebracht:

  • Wenn Sie die Eingabedaten Ihres Batch-Jobs mithilfe eines Datenbank-Cursors aus einer relationalen Datenbank lesen möchten, können Sie den JdbcCursorItemReader<T> erstellen Objekt mit dem JdbcCursorItemReaderBuilder<T> Klasse.
  • Wenn Sie die Eingabedaten Ihres Batch-Jobs aus einer relationalen Datenbank mit Paginierung lesen möchten, können Sie die verwendete Datenbank automatisch erkennen und die entsprechende Paginierungslogik auswählen, indem Sie den SqlPagingQueryProviderFactoryBean konfigurieren Bohne.
  • Wenn Sie die Eingabedaten Ihres Batch-Jobs mithilfe von Paginierung aus einer relationalen Datenbank lesen möchten, können Sie den JdbcPagingItemReader<T> erstellen Objekt mit dem JdbcPagingItemReaderBuilder<T> Klasse.

Der nächste Teil dieses Tutorials beschreibt, wie Sie einen benutzerdefinierten ItemReader implementieren können .


Java-Tag