[JAVA] Aktualisieren Sie die Datenbank regelmäßig mit Spring Batch und My Batis

Ich habe den Code mit Spring Batch, einer der beliebtesten Spring Framework-Funktionen in Java, bei der Arbeit geschrieben, sodass ich ihn zu Hause sowohl zur Einführung als auch zur Überprüfung implementieren werde. Den endgültigen Code finden Sie auf GitHub.

Umgebung

Was zu machen

Ich kann den Code, den ich geschrieben habe, nicht ins Geschäft bringen, also werde ich einen Ersatz machen. Ich entschied mich für eine Charge, die die Altersdaten einer bestimmten persönlichen Tabelle anhand des Geburtsdatums auf das richtige Alter korrigiert.

Daten

Bereiten Sie zuerst die Daten vor. Starten Sie CentOS 7 in Vagrant und installieren Sie dort MySQL. Erstellen Sie eine Datenbank mit dem Namen Batch und bereiten Sie die folgende Tabelle vor. Dieses Mal wäre es schön, wenn ich das Alter und das Geburtsdatum hätte, aber damit bin ich einsam, also habe ich einen Namen vorbereitet. Der Batch soll übrigens täglich ausgeführt werden.

mysql> use batch;
Database changed
mysql> desc person;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| name     | varchar(30) | NO   |     | NULL    |                |
| age      | int(3)      | NO   |     | NULL    |                |
| birthday | date        | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+

Geben Sie Daten für ca. 4 Personen ein. Heute ist der 29. August, also werde ich die Geburtstagsdaten eingeben, die nur im westlichen Kalender anders sind. Ich werde einen Fall am Geburtstag eines anderen Tages vorbereiten, damit ich sehen kann, ob er extra aktualisiert wurde.

mysql> select * from person;
+----+-------+-----+------------+
| id | name  | age | birthday   |
+----+-------+-----+------------+
|  1 | Alice |  23 | 1995-08-29 |
|  2 | Bob   |  38 | 1980-08-29 |
|  3 | Carol |  29 | 1989-08-29 |
|  4 | Dave  |  23 | 1995-08-30 |
+----+-------+-----+------------+

Java-Komponente

Wenn Sie das Spring Framework verwenden, ist es schneller, die Vorlage von Spring Initializr herunterzuladen. Verwenden Sie diese Option. Da Gradle zum Erstellen verwendet wird, wählen Sie Gradle-Projekt aus und geben Sie es entsprechend ein. image.png Abhängigkeiten

Wählen Sie den Bereich entsprechend aus, laden Sie ihn mit "Projekt generieren" herunter und entpacken Sie ihn. Wir werden die erforderlichen Dateien hinzufügen. Die SpringBatch-Architektur wird ausführlich in [hier] beschrieben (https://terasoluna-batch.github.io/guideline/5.2.1.RELEASE/ja/Ch02_SpringBatchArchitecture.html). Ich denke, Sie sollten sie lesen. ..

In SpringBatch ist die Ausführungseinheit des Stapels als JOB und die Verarbeitungseinheit als STEP definiert. Darüber hinaus werden zwei Konzepte, ** Tasklet-Modell ** und ** Chunk-Modell **, als Vorlagen für den STEP-Verarbeitungsablauf bereitgestellt. Ursprünglich denke ich, dass Tasklets ausreichen, wenn Sie nur auf eine einzelne Tabelle verweisen und diese aktualisieren müssen, aber dieses Mal werden wir es wagen, ein Blockmodell zu übernehmen und zu implementieren.

Das Chunk-Modell muss implementiert werden, indem es in drei Abläufe von "Lesen-> Verarbeiten-> Schreiben" unterteilt wird, und für jedes werden Schnittstellen vorbereitet.

Schnittstelle Implementierungsdetails
ItemReader Extrahieren Sie personenbezogene Daten aus der Datenbank, die das gleiche Geburtsdatum wie das Ausführungsdatum haben.
ItemProcessor Berechnen Sie das Alter ab dem Geburtsdatum und erstellen Sie persönliche Daten mit aktualisiertem Alter.
ItemWriter Schreiben Sie die erstellten persönlichen Daten in die DB.

Daten lesen und schreiben

Stellen Sie zum Lesen und Schreiben von Daten eine Verbindung zur Datenbank her. Die Implementierungsklasse für jede Schnittstelle wird von der MyBatis-Bibliothek bereitgestellt, daher werden wir diese verwenden. Read (ItemReader) extrahiert persönliche Datensätze, deren Geburtstag mit dem Datum der Stapelausführung übereinstimmt. Also werde ich das folgende SQL ausgeben. Das Datum des Tages (heute) wird von der App übergeben.

python


SELECT
    id,
    name,
    age,
    birthday
FROM
    person
WHERE
    Date_format(birthday, '%m%d') = Date_format(#{today}, '%m%d')

Beim Schreiben (ItemWriter) wird nur das Alter aktualisiert.

python


update
    person
set
    age = #{age}
where
    id = #{id}

Datenverarbeitung

Bei der Datenverarbeitung (ItemProcessor) liegt es in der Verantwortung, das Alter des extrahierten Objekts für personenbezogene Daten korrekt zu korrigieren. Sie müssen jedoch nur die Differenz zwischen diesem Jahr und dem Geburtsjahr berechnen und ein Aktualisierungsobjekt erstellen.

CorrectAgeProcessor.java


//Import weggelassen
@Component
@Slf4j
public class CorrectAgeProcessor implements ItemProcessor<Person, Person> {
    @Override
    public Person process(Person person) throws Exception {
        log.info("Correct {}.", person.getName());
        return new Person(
                person.getId(),
                person.getName(),
                LocalDate.now().getYear() - person.getBirthday().getYear(),
                person.getBirthday());
    }
}

Definition der Jobkonfiguration

Definieren Sie die Jobkonfiguration. Diesmal reicht ein Schritt aus, bereiten Sie also eine Bohne mit dem Namen "Schritt" vor. Spring Batch scheint standardmäßig die Transaktionsverarbeitung durchzuführen und schreibt in dem durch chunk (n) festgelegten Nummernintervall fest. Der Zweck besteht darin, den Overhead zum Zeitpunkt des Festschreibens zu verringern, indem bis zu einem gewissen Grad gemeinsam festgelegt wird. Dieses Mal werde ich vorerst eins nach dem anderen festlegen.

BatchConfiguration.java


//Import weggelassen
@Configuration
@EnableBatchProcessing
@RequiredArgsConstructor
public class BatchConfiguration {

    public final JobBuilderFactory jobBuilderFactory;

    public final StepBuilderFactory stepBuilderFactory;

    private final SqlSessionFactory sqlSessionFactory;

    private final CorrectAgeProcessor correctAgeProcessor;

    @Bean
    public MyBatisCursorItemReader<Person> reader() {
        Map<String, Object> params = new HashMap<>();
        params.put("today", LocalDate.now());
        return new MyBatisCursorItemReaderBuilder<Person>()
                .sqlSessionFactory(sqlSessionFactory)
                .queryId("com.github.hysrabbit.agecorrector.mybatis.mapper.PersonMapper.findByBirthday")
                .parameterValues(params)
                .build();
    }

    @Bean
    public MyBatisBatchItemWriter<Person> writer() {
        return new MyBatisBatchItemWriterBuilder<Person>()
                .sqlSessionFactory(sqlSessionFactory)
                .statementId("com.github.hysrabbit.agecorrector.mybatis.mapper.PersonMapper.save")
                .build();
    }

    @Bean
    public Job correctAge(JobListener jobListener, Step step) {
        return jobBuilderFactory.get("correctAge")
                .incrementer(new RunIdIncrementer())
                .listener(jobListener)
                .flow(step)
                .end()
                .build();
    }

    @Bean
    public Step step(ItemReader<Person> reader, ItemWriter<Person> writer) {
        return stepBuilderFactory.get("step")
                .<Person, Person> chunk(1)
                .reader(reader)
                .processor(correctAgeProcessor)
                .writer(writer)
                .build();
    }

}

Ich habe alles andere implementiert und den endgültigen Code auf [hier] verschoben (https://github.com/hys-rabbit/AgeCorrector). Ich habe den Testcode nicht implementiert, daher werde ich versuchen, ihn bald zu implementieren.

Die Ausführung erfolgt auf der VM, auf der MySQL installiert ist. Definieren Sie vor der Ausführung die DB-Einstellungsinformationen in der Umgebungsvariablen.

$ export SPRING_DATASOURCE_URL=jdbc:mysql://<hostname>:<port>/<database>;
$ export SPRING_DATASOURCE_USERNAME=<username>;
$ export SPRING_DATASOURCE_PASSWORD=<password>;

Erstellen Sie dann mit Gradle und führen Sie die resultierende Jar-Datei aus. Der Name der Person, die ihn aktualisiert hat, wird im eingefügten Logger ausgegeben.

$ ./gradlew clean build
.
.
.
$ java -jar build/libs/agecorrector.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.7.RELEASE)
.
.
.
2019-08-29 01:50:29.334  INFO 2781 --- [           main] c.g.h.agecorrector.batch.JobListener     : Start job.
2019-08-29 01:50:29.391  INFO 2781 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step]
2019-08-29 01:50:29.565  INFO 2781 --- [           main] c.g.h.a.batch.CorrectAgeProcessor        : Correct Alice.
2019-08-29 01:50:29.609  INFO 2781 --- [           main] c.g.h.a.batch.CorrectAgeProcessor        : Correct Bob.
2019-08-29 01:50:29.624  INFO 2781 --- [           main] c.g.h.a.batch.CorrectAgeProcessor        : Correct Carol.
2019-08-29 01:50:29.651  INFO 2781 --- [           main] c.g.h.agecorrector.batch.JobListener     : Completed job.
.
.
.

Lassen Sie uns auch die Daten in MySQL überprüfen. Der Tag, an dem ich lief, war "8/29", aber Sie können das Alter der an diesem Tag geborenen Person aktualisieren.

mysql> select * from person;
+----+-------+-----+------------+
| id | name  | age | birthday   |
+----+-------+-----+------------+
|  1 | Alice |  24 | 1995-08-29 |
|  2 | Bob   |  39 | 1980-08-29 |
|  3 | Carol |  30 | 1989-08-29 |
|  4 | Dave  |  23 | 1995-08-30 |
+----+-------+-----+------------+

Zusammenfassung

Wenn Sie sich danach bei Cron usw. registrieren, können Sie Ihr Alter regelmäßig aktualisieren. Ich denke, die Kombination von Spring Batch und My Batis ist ein leicht verständliches und benutzerfreundliches Framework für Java-Programmierer. Es gibt auch viele nützliche Funktionen, die dieses Mal in Spring Batch nicht implementiert sind. Verwenden Sie sie daher auf jeden Fall.

Referenz

Recommended Posts

Aktualisieren Sie die Datenbank regelmäßig mit Spring Batch und My Batis
Kompatibilität von Spring JDBC und My Batis mit Spring Data JDBC (vorläufig)
Feder mit Kotorin --2 RestController und Datenklasse
Erstellen Sie mit Spring Batch eine einfache On-Demand-Charge
DB-Authentifizierung mit Spring Security und Hashing mit BCrypt
HTTPS mit Spring Boot und Let's Encrypt
Implementierungsmethode für Multi-Datenquelle mit Spring Boot (Mybatis und Spring Data JPA)
Beispiel für Batch-Prozessdaten in der Datenbank mit Apache Camel Spring Boot-Startern
Geben Sie einfach Bilder mit Spring MVC ein und geben Sie sie aus
Spring Batch 4.1.x - Referenzdokumentation Gelesen und übersetzt
Verwendung von MyBatis2 (iBatis) mit Spring Boot 1.4 (Spring 4)
[Anfänger] Laden Sie Bilder und Dateien mit Spring hoch [Autark]
Erstellen Sie eine CRUD-App mit Spring Boot 2 + Thymeleaf + MyBatis
[JAVA] [Spring] [MyBatis] Verwenden Sie IN () mit SQL Builder
Sie können @Param mit Kotlin 1.1 und MyBatis 3.4.1+ eliminieren! !!
Versuchen Sie es mit einem DI-Container mit Laravel und Spring Boot
Wechseln Sie die Umgebung mit Spring Boot application.properties und @ Profile-Annotation
Verwendungshinweis zu Spring Security: Zusammenarbeit mit Spring MVC und Boot
Spring Boot mit Spring Security Filter-Einstellungen und Suchtpunkten
Versuch, SSR Vue.js mit Spring Boot und GraalJS zu verwenden
[Spring Batch] Überprüfung der Implementierung von Chunk Step und Tasklet Step von Spring Batch
Steuern Sie den Spring Batch-Verarbeitungsablauf mit JavaConfig.
Verbinden Sie Spring Boot und Angular typsicher mit OpenAPI Generator