[JAVA] [Spring Batch] Gibt Tabellendaten in eine CSV-Datei aus

Einführung

Ich habe versucht, Stapelverarbeitung mit Tasklet. Ich verwende auch MyBatis-Cursor, um das Massenladen von Tabellen zu handhaben.

Ein Projekt erstellen

Erstellen Sie ein Projekt mit Spring Initializr. Wählen Sie unter Abhängigkeiten Batch, Lombok, MyBatis und den DBC-Treiber für Ihre Datenbank aus (Mein Artikel verwendet MySQL).

Einstellungsdatei

application.properties


#Protokollstufe
logging.level.com.sample.demo=debug

#DB-Verbindungsinformationen
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8&serverTimezone=JST&sslMode=DISABLED
spring.datasource.username=hoge
spring.datasource.password=hoge

#Größe holen
#mybatis.configuration-properties.default-fetch-size=10000
mybatis.configuration-properties.fetch-size=10000

#Dateischreibgröße
demo.write-size=1000

Quelle

Lesen Sie die Datenbank und geben Sie die Datei aus.

DemoTasklet.java


package com.sample.demo;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.cursor.Cursor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ItemStreamWriter;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component()
public class DemoTasklet implements Tasklet {
	private Logger logger = LoggerFactory.getLogger(DemoTasklet.class);

	@Autowired
	private DemoRepository demoRepository;

	@Autowired
	private ItemStreamWriter<DemoDTO> writer;

	@Autowired
	private DemoContext demoContext;

	public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
		logger.debug("DemoTasklet Start ausführen");

		writer.open(chunkContext.getStepContext().getStepExecution().getExecutionContext());
		try(Cursor<DemoDTO> result = demoRepository.select()) {
			List<DemoDTO> data = new ArrayList<>();
			for(DemoDTO dto: result) {
				data.add(dto);
				if (data.size() >= demoContext.getWriteSize()) {
					writer.write(data);
					data.clear();
				}
			}
			if (data.size() > 0) writer.write(data);
		}
		writer.close();

		logger.debug("DemoTasklet-Ausführung beendet");
		return RepeatStatus.FINISHED;
	}

}

Registrieren Sie das Tasklet und legen Sie die CSV-Datei fest.

BatchConfig.java


package com.sample.demo;

import java.io.IOException;
import java.io.Writer;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.file.FlatFileHeaderCallback;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

@Configuration
@EnableBatchProcessing
public class BatchConfig {
	@Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private DemoTasklet demoTasklet;

    private Resource outputResource = new FileSystemResource("output/data.csv");

    @Bean
    public DemoContext createDemoContext() {
    	return new DemoContext();
    }

	@Bean
	public FlatFileItemWriter<DemoDTO> writer()
	{
		FlatFileItemWriter<DemoDTO> writer = new FlatFileItemWriter<>();
		writer.setResource(outputResource);
		writer.setEncoding("UTF-8");
		writer.setLineSeparator("\r\n");
		writer.setAppendAllowed(false);

		writer.setHeaderCallback(new FlatFileHeaderCallback() {
			public void writeHeader(Writer arg0) throws IOException {
				arg0.append("\"ID\",\"Name\",\"Mail Adresse\"");
			}
		});

		writer.setLineAggregator(new CsvLineAggregator<DemoDTO>() {
			{
				setFieldExtractor(new BeanWrapperFieldExtractor<DemoDTO>() {
					{
						setNames(new String[] { "id", "name", "mailAddress" });
					}
				});
			}
		});

		return writer;
    }

	@Bean
	public Step step1() {
		return stepBuilderFactory.get("step1").tasklet(demoTasklet).build();
	}

	@Bean
	public Job job(Step step1) {
		return jobBuilderFactory.get("job").incrementer(new RunIdIncrementer()).start(step1).build();
	}
}

Der in [demo.] In application.properties definierte Schlüsselwert wird festgelegt.

DemoContext.java


package com.sample.demo;

import org.springframework.boot.context.properties.ConfigurationProperties;

import lombok.Data;

@ConfigurationProperties(prefix="demo")
@Data
public class DemoContext {
	private int writeSize;
}

Wenn Sie die bis zum Frühjahr vorbereitete Klasse verwenden, können Sie das Box-Zeichen nicht festlegen. Wenn Sie also das Box-Zeichen festlegen möchten, müssen Sie ein eigenes erstellen.

CsvLineAggregator.java


package com.sample.demo;

import java.util.Arrays;

import org.springframework.batch.item.file.transform.ExtractorLineAggregator;
import org.springframework.util.StringUtils;

public class CsvLineAggregator<T> extends ExtractorLineAggregator<T> {

	private String enclose = "\"";

	private String delimiter = ",";

	public void setEnclose(String enclose) {
		this.enclose = enclose;
	}

	public void setDelimiter(String delimiter) {
		this.delimiter = delimiter;
	}

	@Override
	protected String doAggregate(Object[] fields) {
		return StringUtils.collectionToDelimitedString(Arrays.asList(fields), this.delimiter, this.enclose, this.enclose);
	}

}

DTO

DemoDTO.java


package com.sample.demo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Data
public class DemoDTO {
	private String id;
	private String name;
	private String mailAddress;
}

Schnittstelle für SQL

DemoRepository.java


package com.sample.demo;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.cursor.Cursor;

@Mapper
public interface DemoRepository {

	Cursor<DemoDTO> select();

}

SQL

DemoRepository.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.sample.demo.DemoRepository">

    <select id="select" resultType="com.sample.demo.DemoDTO" fetchSize="${fetch-size}">
      SELECT
        id,
        name,
        mail_address as mailAddress
      FROM
        users
    </select>
</mapper>

Recommended Posts

[Spring Batch] Gibt Tabellendaten in eine CSV-Datei aus
Fluss bis zur Ausgabe von Tabellendaten, die mit Spring Boot angezeigt werden sollen
Ausgabe einer CSV-Datei mit offener CSV
JavaDoc in Word-Datei ausgeben
XML-Baum in Datei ausgeben
Hinweise zur Verwendung von Spring Data JDBC
[So installieren Sie Spring Data Jpa]
Protokollausgabe in Datei in Java
Spring Data JPA SQL-Protokollausgabe
Ich habe ein Tool erstellt, um den Unterschied zwischen CSV-Dateien auszugeben
Migrationsdatei zum Hinzufügen eines Kommentars zur Rails-Tabelle
Antwortdaten direkt im Frühjahr schreiben
Ruby: CSV :: Verwendung von Table Note
So teilen Sie eine Spring Boot-Nachrichtendatei
Ausgabe Bean als JSON im Frühjahr
Beispiel für Batch-Prozessdaten in der Datenbank mit Apache Camel Spring Boot-Startern
[Ruby] So konvertieren Sie eine CSV-Datei in Yaml (Yml)
So geben Sie die von Rails erstellte CSV in S3 aus
Spring Data REST HAL Browser bestätigt den Spring REST-Vorgang
Einführung in Spring Boot + In-Memory Data Grid
Ich habe versucht, neunundneunzig in Java auszugeben
So binden Sie mit einer Eigenschaftendatei in Spring Boot
[Spring Boot] So verweisen Sie auf die Eigenschaftendatei
Ich habe versucht, das Hochladen von Dateien mit Spring MVC zu implementieren
Ich habe versucht, CSV mit Outsystems zu lesen und auszugeben
Protokoll mit slf4j + Logback mit Maven in externe Datei ausgeben
Ich habe versucht, mit Spring Data JPA zu beginnen
[Java] [Spring] [Spring Batch] Erstellen / verwenden Sie keine Spring Batch-Metadatentabelle
Konvertieren Sie die CSV-Datei mit enum in eine Datensatzdatei mit fester Länge
So testen Sie den Bildschirm zum Hochladen von Dateien mit Spring + Selenium
Verwendung des In-Memory-Job-Repositorys mit Spring Batch