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.
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.
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 |
+----+-------+-----+------------+
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. 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. |
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}
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());
}
}
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 |
+----+-------+-----+------------+
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.
Recommended Posts