Composant Spring Batch ItemReader - lire des fichiers plats

Table des matières

ItemReader

lire des fichiers plats

Cas 1

Cas 2

Passer à la version vidéo


Continuez avec l'article précédent : Redémarrage du travail Spring Batch , après avoir compris la méthode de redémarrage du travail Spring Batch, découvrons les composants de lecture Spring Batch et comment Spring Batch lit les données de fichiers plats.

ItemReader

Les étapes de l'opération de bloc sont composées d'un ItemReader, d'un ItemProcessor et d'un ItemWriter. L'un est responsable de la lecture des données, l'autre est responsable du traitement des données et l'autre est responsable de la sortie des données. Après les étapes du chapitre précédent, nous se concentrera sur les composants d'entrée Spring Batch: ItemReader

ItemReader est un composant d'entrée fourni par Spring Batch. L'interface standard est ItemReader<T>, qui a une méthode read(). Nous pouvons implémenter cette interface pour personnaliser la logique d'entrée.

public interface ItemReader<T> {
	@Nullable
	T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException;
}

Spring Batch fournit de nombreuses implémentations par défaut basées sur les types d'entrée couramment utilisés, notamment : les fichiers plats, les bases de données, les ressources JMS et d'autres sources d'entrée. Ensuite, exploitons les scénarios d'entrée des scénarios de comparaison.

lire des fichiers plats

Les fichiers plats font généralement référence à des fichiers de texte brut avec une structure simple ligne/multiligne, tels que des fichiers d'enregistrement de bloc-notes. La différence avec xml est qu'il n'y a pas de structure ni de restriction d'étiquette. Spring Batch utilise FlatFileItemReader par défaut pour implémenter une entrée de fichier plat. Ensuite, l'utilisation de la classe FlatFileItemReader sera expliquée sous la forme d'un cas.

Cas 1

Exigences : Lisez le fichier user.txt et analysez toutes les informations de l'utilisateur

user.txt, placé dans le fichier de ressources (classpath path)

1#dafei#18
2#xiaofei#16
3#laofei#20
4#zhongfei#19
5#feifei#15

Classe d'entité

@Getter
@Setter
@ToString
public class User {
    private Long id;
    private String name;
    private int age;
}

faire ses devoirs

package com.langfeiyes.batch._21_itemreader_flat;

import com.langfeiyes.batch._20_job_restart_allow.JobAllowRestartJob;
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.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.util.List;

@SpringBootApplication
@EnableBatchProcessing
public class FlatReaderJob {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public FlatFileItemReader<User> userItemReader(){
        return new FlatFileItemReaderBuilder<User>()
                .name("userItemReader")
            	.resource(new ClassPathResource("users.txt"))
                .delimited().delimiter("#")
                .names("id", "name", "age")
                .targetType(User.class)
                
                .build();
    }

    @Bean
    public ItemWriter<User> itemWriter(){
        return new ItemWriter<User>() {
            @Override
            public void write(List<? extends User> items) throws Exception {
                items.forEach(System.err::println);
            }
        };
    }

    @Bean
    public Step step(){
        return stepBuilderFactory.get("step1")
                .<User, User>chunk(1)
                .reader(userItemReader())
                .writer(itemWriter())
                .build();

    }

    @Bean
    public Job job(){
        return jobBuilderFactory.get("flat-reader-job")
                .start(step())
                .build();
    }
    public static void main(String[] args) {
        SpringApplication.run(FlatReaderJob.class, args);
    }
}

Le noyau se trouve dans la méthode d'instance userItemReader()

//FlatFileItemReader spring batch 平面文件读入类
//这个类操作特点:一行一行的读数据
@Bean
public FlatFileItemReader<User> userItemReader(){
    return new FlatFileItemReaderBuilder<User>()
        .name("userItemReader")
        .resource(new ClassPathResource("users.txt"))  //指定读取的文件
        .delimited().delimiter("#")  //读取出一行数据,该如何分割数据,默认以,分割,当前使用#号分割
        .targetType(User.class)      //读取出一行数据封装成什么对象
        //给分割后数据打name标记,后续跟User对象属性进行映射
        .names("id", "name", "age")  
        .build();
}

Cas 2

Exigences : Lire le fichier user2.txt et analyser toutes les informations de l'utilisateur

utilisateur2.txt

1#dafei#18#广东#广州#天河区
2#xiaofei#16#四川#成都#武侯区
3#laofei#20#广西#桂林#雁山区
4#zhongfei#19#广东#广州#白云区
5#feifei#15#广东#广州#越秀区

De toute évidence, les données se sont avérées plus compliquées.

objet utilisateur

@Getter
@Setter
@ToString
public class User {
    private Long id;
    private String name;
    private int age;
    private String address;
}

Observez qu'il y a id name age province city area dans le fichier user2.txt. Logiquement, les attributs de l'objet utilisateur devraient être une correspondance un à un, mais pour le moment l'utilisateur n'a que l'adresse, c'est-à-dire la province, la ville, La zone sera combinée ultérieurement en valeur d'adresse d'adresse. Que devons-nous faire maintenant? C'est la nécessité de personnaliser FieldSetMapper.

public class UserFieldMapper implements FieldSetMapper<User> {
    @Override
    public User mapFieldSet(FieldSet fieldSet) throws BindException {

        //自己定义映射逻辑
        User User = new User();
        User.setId(fieldSet.readLong("id"));
        User.setAge(fieldSet.readInt("age"));
        User.setName(fieldSet.readString("name"));
        String addr = fieldSet.readString("province") + " "
                + fieldSet.readString("city") + " " + fieldSet.readString("area");
        User.setAddress(addr);
        return User;
    }
}

Le code ci-dessus réalise le mappage entre l'objet FieldSet et l'objet utilisateur et fusionne la zone de la ville de la province en une seule adresse d'attribut. De plus, readXxx est une méthode unique de FieldSet et Xxx est un type de base de Java.

package com.langfeiyes.batch._22_itemreader_flat_mapper;

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.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;

import java.util.List;

@SpringBootApplication
@EnableBatchProcessing
public class MapperFlatReaderJob {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public UserFieldMapper userFieldMapper(){
        return new UserFieldMapper();
    }


    @Bean
    public FlatFileItemReader<User> userItemReader(){
        return new FlatFileItemReaderBuilder<User>()
                .name("userMapperItemReader")
                .resource(new ClassPathResource("users2.txt"))
                .delimited().delimiter("#")
                .names("id", "name", "age", "province", "city", "area")
                .fieldSetMapper(userFieldMapper())
                .build();
    }

    @Bean
    public ItemWriter<User> itemWriter(){
        return new ItemWriter<User>() {
            @Override
            public void write(List<? extends User> items) throws Exception {
                items.forEach(System.err::println);
            }
        };
    }

    @Bean
    public Step step(){
        return stepBuilderFactory.get("step1")
                .<User, User>chunk(1)
                .reader(userItemReader())
                .writer(itemWriter())
                .build();

    }

    @Bean
    public Job job(){
        return jobBuilderFactory.get("mapper-flat-reader-job")
                .start(step())
                .build();
    }
    public static void main(String[] args) {
        SpringApplication.run(MapperFlatReaderJob.class, args);
    }
}

Le cœur du code ci-dessus se trouve dans la méthode d'instance de userItemReader

.fieldSetMapper(userFieldMapper()) : Utiliser un mappeur de champs personnalisé

.names("id", "name", "age", "province", "city", "area") : Chaque ligne de users2.txt utilise # pour diviser et apparaître 6 colonnes, donner un nom à chaque colonne, et puis encapsulez-le dans l'objet FieldSet

.targetType(User.class) : Notez qu'après avoir utilisé fieldSetMapper, il n'est pas nécessaire d'ajouter cette ligne

À ce stade, cet article est terminé. Si vous voulez savoir ce qui va se passer ensuite, veuillez écouter le chapitre suivant pour le décomposer ~

Passer à la version vidéo

Si vous n'êtes pas accro à la lecture de texte, vous pouvez passer à la version vidéo : Framework de traitement par lots efficace Spring Batch en pratique

Guess you like

Origin blog.csdn.net/langfeiyes/article/details/128933866