spring 导出csv_Spring批处理CSV处理

spring 导出csv

总览

我们将讨论的主题包括使用Spring Batch进行批处理的基本概念,以及如何将数据从CSV导入数据库。

0 – Spring Batch CSV处理示例应用程序

我们正在构建一个应用程序,演示用于处理CSV文件的Spring Batch的基础。 我们的演示应用程序将允许我们处理CSV文件,其中包含数百条日本动漫标题的记录。

0.1 – CSV

我已经从这个Github存储库中下载了将要使用的CSV文件,它提供了相当全面的动漫列表。

这是在Microsoft Excel中打开的CSV的屏幕截图

查看并从 Github 下载代码

1 –项目结构

2 –项目依赖性

除了典型的Spring Boot依赖关系之外,我们还包括spring-boot-starter-batch(这是对Spring Batch的依赖,顾名思义)和hsqldb(对于内存数据库)。 我们还包括ToStringBuilder的commons-lang3。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.michaelcgood</groupId><artifactId>michaelcgood-spring-batch-csv</artifactId><version>0.0.1</version><packaging>jar</packaging><name>michaelcgood-spring-batch-csv</name><description>Michael C  Good - Spring Batch CSV Example Application</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.7.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-batch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.hsqldb</groupId><artifactId>hsqldb</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.6</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3 –模型

这是对动漫领域进行建模的POJO。 这些字段是:

  • ID。 为了简单起见,我们将ID视为字符串。 但是,可以将其更改为其他数据类型,例如Integer或Long。
  • 标题。 这是动画的标题,适合作为String。
  • 描述。 这是动漫的描述,比标题长,也可以视为字符串。

需要注意的是我们的三个字段的类构造函数:public AnimeDTO(String id,String title,String description)。 这将在我们的应用程序中使用。 同样,像往常一样,我们需要创建一个没有参数的默认构造函数,否则Java会抛出错误。

package com.michaelcgood;import org.apache.commons.lang3.builder.ToStringBuilder;
/*** Contains the information of a single anime** @author Michael C Good michaelcgood.com*/public class AnimeDTO {public String getId() {return id;}public void setId(String id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}private String id;private String title;private String description;public AnimeDTO(){}public AnimeDTO(String id, String title, String description){this.id = id;this.title = title;this.description = title;}@Overridepublic String toString() {return new ToStringBuilder(this).append("id", this.id).append("title", this.title).append("description", this.description).toString();}}

4 – CSV文件到数据库配置

该类中发生了很多事情,并且不是一次编写的,因此我们将逐步学习代码。 访问Github以查看完整的代码。

4.1 –读者

如Spring Batch文档所述,FlatFileIteamReader将“从平面文件中读取数据行,这些文件通常描述记录的数据字段由文件中的固定位置定义或由某些特殊字符(例如逗号)分隔”。

我们正在处理CSV,因此当然用逗号分隔数据,这使其非常适合与我们的文件一起使用。

@Beanpublic FlatFileItemReader<AnimeDTO> csvAnimeReader(){FlatFileItemReader<AnimeDTO> reader = new FlatFileItemReader<AnimeDTO>();reader.setResource(new ClassPathResource("animescsv.csv"));reader.setLineMapper(new DefaultLineMapper<AnimeDTO>() {{setLineTokenizer(new DelimitedLineTokenizer() {{setNames(new String[] { "id", "title", "description" });}});setFieldSetMapper(new BeanWrapperFieldSetMapper<AnimeDTO>() {{setTargetType(AnimeDTO.class);}});}});return reader;}

要点:

    • FlatFileItemReader使用模型进行参数化。

4.2 –处理器

如果要在将数据写入数据库之前对其进行转换,则需要一个ItemProcessor。 我们的代码实际上并没有应用任何业务逻辑来转换数据,但是我们允许这种能力。

4.2.1 – CsvFileToDatabaseConfig.Java中的处理器

csvAnimeProcessor返回AnimeProcessor对象的新实例,我们将在下面进行检查。

@BeanItemProcessor<AnimeDTO, AnimeDTO> csvAnimeProcessor() {return new AnimeProcessor();}

4.2.2 – AnimeProcessor.Java

如果我们想在写入数据库之前应用业务逻辑,则可以在写入数据库之前操纵字符串。 例如,您可以在getTitle之后添加toUpperCase()以使标题大写,然后再写入数据库。 但是,我决定不对此示例处理器执行此操作或不应用任何其他业务逻辑,因此未进行任何操作。 该处理器仅在此处进行演示。

package com.michaelcgood;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import org.springframework.batch.item.ItemProcessor;public class AnimeProcessor implements ItemProcessor<AnimeDTO, AnimeDTO> {private static final Logger log = LoggerFactory.getLogger(AnimeProcessor.class);@Overridepublic AnimeDTO process(final AnimeDTO AnimeDTO) throws Exception {final String id = AnimeDTO.getId();final String title = AnimeDTO.getTitle();final String description = AnimeDTO.getDescription();final AnimeDTO transformedAnimeDTO = new AnimeDTO(id, title, description);log.info("Converting (" + AnimeDTO + ") into (" + transformedAnimeDTO + ")");return transformedAnimeDTO;}}

4.3 –作家

csvAnimeWriter方法负责将值实际写入我们的数据库。 我们的数据库是内存中的HSQLDB,但是此应用程序使我们可以轻松地将一个数据库换成另一个数据库。 数据源是自动接线的。

@Beanpublic JdbcBatchItemWriter<AnimeDTO> csvAnimeWriter() {JdbcBatchItemWriter<AnimeDTO> excelAnimeWriter = new JdbcBatchItemWriter<AnimeDTO>();excelAnimeWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<AnimeDTO>());excelAnimeWriter.setSql("INSERT INTO animes (id, title, description) VALUES (:id, :title, :description)");excelAnimeWriter.setDataSource(dataSource);return excelAnimeWriter;}

4.4 –步骤

步骤是一个域对象,它包含批处理作业的独立顺序阶段,并包含定义和控制实际批处理所需的所有信息。

现在,我们已经为数据创建了读取器和处理器,我们需要编写数据。 对于读取,我们一直在使用面向块的处理,这意味着我们一次读取了一个数据。 面向块的处理还包括在事务边界内创建将被写出的“块”。 对于面向块的处理,您可以设置提交间隔,一旦读取的项目数等于已设置的提交间隔,就可以通过ItemWriter写入整个块,并提交事务。 我们将块间隔大小设置为1。

我建议阅读有关批处理的Spring Batch文档 。

然后,读取器,处理器和写入器调用我们编写的方法。

@Beanpublic Step csvFileToDatabaseStep() {return stepBuilderFactory.get("csvFileToDatabaseStep").<AnimeDTO, AnimeDTO>chunk(1).reader(csvAnimeReader()).processor(csvAnimeProcessor()).writer(csvAnimeWriter()).build();}

4.5 –工作

作业由步骤组成。 我们将参数传递到下面的Job中,因为我们想跟踪Job的完成情况。

@BeanJob csvFileToDatabaseJob(JobCompletionNotificationListener listener) {return jobBuilderFactory.get("csvFileToDatabaseJob").incrementer(new RunIdIncrementer()).listener(listener).flow(csvFileToDatabaseStep()).end().build();}

5 –作业完成通知监听器

下面的类将自动连接JdbcTemplate,因为我们已经设置了dataSource并且希望轻松进行查询。 我们的查询结果是AnimeDTO对象的列表。 对于返回的每个对象,我们将在控制台中创建一条消息,以显示该项目已被写入数据库。

package com.michaelcgood;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;@Component
public class JobCompletionNotificationListener extends JobExecutionListenerSupport {private static final Logger log = LoggerFactory.getLogger(JobCompletionNotificationListener.class);private final JdbcTemplate jdbcTemplate;@Autowiredpublic JobCompletionNotificationListener(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic void afterJob(JobExecution jobExecution) {if(jobExecution.getStatus() == BatchStatus.COMPLETED) {log.info("============ JOB FINISHED ============ Verifying the results....\n");List<AnimeDTO> results = jdbcTemplate.query("SELECT id, title, description FROM animes", new RowMapper<AnimeDTO>() {@Overridepublic AnimeDTO mapRow(ResultSet rs, int row) throws SQLException {return new AnimeDTO(rs.getString(1), rs.getString(2), rs.getString(3));}});for (AnimeDTO AnimeDTO : results) {log.info("Discovered <" + AnimeDTO + "> in the database.");}}}}

6 – SQL

我们需要为我们的数据库创建一个模式。 如前所述,我们将所有字段都设置为字符串以方便使用,因此我们将其数据类型设置为VARCHAR。

DROP TABLE animes IF EXISTS;
CREATE TABLE animes  (id VARCHAR(10),title VARCHAR(400),description VARCHAR(999)
);

6 –主

这是带有main()的标准类。 如Spring文档所述, @SpringBootApplication是一个方便注释,其中包括@ Configuration@EnableAutoConfiguration@ EnableWebMvc@ComponentScan

package com.michaelcgood;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBatchCsvApplication {public static void main(String[] args) {SpringApplication.run(SpringBatchCsvApplication.class, args);}
}

7 –演示

7.1 –转换

FieldSet通过处理器输入,“ Converting”被打印到控制台。

7.2 –在数据库中发现新项目

当Spring Batch Job完成时,我们选择所有记录并将它们分别打印到控制台。

7.3 –批处理完成

批处理完成后,这就是打印到控制台的内容。

Job: [FlowJob: [name=csvFileToDatabaseJob]] completed with the following parameters: [{run.id=1, -spring.output.ansi.enabled=always}] and the following status: [COMPLETED]
Started SpringBatchCsvApplication in 36.0 seconds (JVM running for 46.616)

8 –结论

Spring Batch建立在基于POJO的开发方法和Spring Framework的用户友好性的基础上,使开发人员可以轻松地创建企业级批处理。

源代码在 Github上

翻译自: https://www.javacodegeeks.com/2017/10/spring-batch-csv-processing.html

spring 导出csv

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334725.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python强制结束函数_为什么Python没有 main 函数?终于有人给出了正确答案!

毫无疑问&#xff0c;Python中没有所谓的 main 入口函数&#xff0c;但在网上经常有文章提到“Python中的main函数”和“建议编写main函数”等。他们的目的可能是模仿真实的 main 函数&#xff0c;但是经常有很多人被误导&#xff08;或误解&#xff09;并编写非常繁琐的代码。…

MacOS 如何显示/隐藏文件

文章目录显示/隐藏文件快捷键修改“访达”属性修改文件隐藏属性设置特殊文件名实现隐藏使用命令设置文件隐藏属性显示/隐藏文件 快捷键 按下 Shift Command . 可以显示隐藏型的文件&#xff0c;再按下 Shift Command . 则不显示隐藏型的文件 修改“访达”属性 defaults…

html标签的嵌套规则有哪些,html 标签的嵌套规则

如何在 Visual Studio 中使用 Git 同步代码到 CodePlex开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework.ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐.CodePlex 则是 ...【android】Android am命令使用一.开启Activ…

lombok_Lombok–您绝对应该尝试一下

lombokLombok在Java生态系统中并不是什么新鲜事物&#xff0c;但是我必须承认&#xff0c;在尝试它之前或在我“很确信”尝试之前&#xff0c;我总是低估了它的价值。 我发现添加一个库来生成代码的价值并不高&#xff0c;这些库可以被当今的任何现代IDE轻松生成。 因此&#x…

不相关子查询的工作方式是_课题组工作|Nucleic Acids Research|基于表达密度谱的特征子空间分离及相关单细胞转录组分群新算法...

大家好&#xff01;为大家分享本课题组近期发表在Nucleic Acids Research的文章&#xff0c;题目为 “Entropy subspace separation-based clustering for noise reduction (ENCORE) of scRNA-seq data”&#xff0c;文章提出了一种基于表达密度谱的特征选择方法&#xff0c;能…

Mac OS 使用命令(scp/sftp)将本地文件上传到远程 Linux 服务器主机或者从远程主机下载文件到本地主机

文章目录一、使用 scp 命令&#xff08;一&#xff09;将本地的文件上传&#xff08;上载/复制&#xff09;到远程主机的指定目录下&#xff08;二&#xff09;将本地主机的目录内容&#xff08;含目录本身&#xff09;上传到远程主机指定的目录下1.将本地主机桌面上的目录 www…

java 9 module_Java 9:欢迎来到Module World

java 9 moduleJava 9已于9月21日正式发布&#xff0c;Eclipse从Eclipse Oxygen.1a&#xff08;4.7.1a&#xff09;支持Java 9&#xff0c;让我们进入模块世界。 从此处下载Java 9&#xff0c;并将其添加到Eclipse Installed JRE中&#xff0c;如下所示 就是这样&#xff0c;…

python提取html正文为txt,python 提取html文本的方法

假设我们需要从各种网页中提取全文&#xff0c;并且要剥离所有HTML标记。通常&#xff0c;默认解决方案是使用BeautifulSoup软件包中的get_text方法&#xff0c;该方法内部使用lxml。这是一个经过充分测试的解决方案&#xff0c;但是在处理成千上万个HTML文档时可能会非常慢。通…

Mac OS 通过配置窗口来连接远程主机

点击连接后&#xff0c;就跳到命令终端窗口中&#xff0c;输入远程主机 root 用户的登录密码&#xff0c;则完成连接。

温度补偿计算公式_一种工业用温度测量模块的设计与实现

一种工业用温度测量模块的设计与实现罗伯特侯0 引言温度是工业生产中最重要的参数之一&#xff0c;因此温度测量设备在工业领域不可或缺。热电偶是工业场合中应用最广泛的温度传感器,它的主要特点是测温范围宽,价格低&#xff0c;同时结构简单,坚固耐用。笔者采用高集成度、高精…

taskexecutor_弹簧和线程:TaskExecutor

taskexecutor在Web应用程序中使用线程并不罕见&#xff0c;尤其是当您必须开发长期运行的任务时。 考虑到spring&#xff0c;我们必须格外注意并使用它已经提供的工具&#xff0c;而不是生成我们自己的线程。 我们希望线程由spring管理&#xff0c;因此能够在没有任何影响的情…

Linux 命令之 find -- 查找文件和目录/搜索文件和目录

文章目录命令介绍语法格式常用选项文件类型参考示例&#xff08;一&#xff09;在当前目录及其子目录下搜索内容中含有“140.206.111.111”的所有文件&#xff08;二&#xff09;列出当前目录及其子目录下所有文件和目录&#xff08;三&#xff09;在指定目录下查找特定名称的文…

javaserver_什么是JavaServer Faces(JSF)–(第2部分)

javaserverFacelets声明语言 在第1部分中&#xff0c;我介绍了JavaServer Pages&#xff08;JSF&#xff09;背后的基本思想 。 在本文中&#xff0c;我想介绍Facelets声明语言 。 HTML标签 我们遇到的第一个标签是代表HTML元素HTML标签。 这些实际上只是HTML标记&#xff08;…

微博如何发订阅消息_微信订阅号或将大变天,微博8年前就这么干了...

近日&#xff0c;微信又偷偷的做了一个大胆的尝试&#xff0c;将公众号消息排序改版&#xff0c;不再按照一直以来的“时间轴展示”&#xff0c;而是学起了微博&#xff0c;变成了“智能排序”。微信的“阅读效率优化”排序不过可能是为了独树一帜&#xff0c;微信管这种排序方…

html怎么填充颜色渐变,CSS实现不规则图形,填充渐变色

JS Bin/* 背景图片实现 */.background-box {width: 400px;height: 100px;/* 透明色替换为当前背景底色 */background:linear-gradient(-135deg, transparent 50px, red , yellow) top right;background-size: 50% 50%;background-repeat: no-repeat;}/* 边框实现 */.border-box…

Linux 命令之 locate -- 文件查找工具(查找文件/搜索文件)

文章目录一、命令介绍二、相关文件说明配置文件 updatedb.conf三、更新数据库四、常用选项五、命令示例搜索文件名以指定字符串开头的文件查找名称中含有指定字符串的文件使用正则表达式查找特定条件的文件一、命令介绍 locate 命令用来查找文件或目录。 locate 命令要比 find…

算法正义_正义联盟的Sprint Boot

算法正义正义联盟&#xff08;Justice League&#xff09;进入了黑暗时代&#xff0c;强大的Darkseid征服了人类。 蝙蝠侠在《神力女超人》的帮助下&#xff0c;努力使联盟与一个关键方面失联。 适当的正义联盟成员管理系统。 由于时间不在他们身边&#xff0c;他们不想经历繁琐…

indesign如何画弧线_彩铅画入门教程,如何给独角兽设计一款好发型

戳这里 → 查看“爱蜜干货文章目录”本次综合训练的目的1&#xff0e;挖掘你的绘画感和想象力&#xff0c;彩色鬃毛色彩大家可以自由发挥哦&#xff01;2.练习彩铅的长线条&#xff0c;现在练习的长条还是比较简单的&#xff0c;下次综合训练我们还会练习更加复杂的3.彩铅这种画…

微型计算机作为载体的部件是,大工11秋《计算机应用基础》辅导资料二

计算机应用基础辅导资料二主题&#xff1a;计算机基础知识的辅导资料学习时间&#xff1a;2011年10月10日&#xff0d;10月16日内容&#xff1a;这周我们主要学习课件&#xff0e;&#xff0e;第二章计算机的基础知识&#xff0c;本章的学习要求及需要掌握的重点内容如下&#…

Linux 命令之 whereis -- 显示命令及相关文件的路径

文章目录一、命令介绍二、选项参数三、参考示例&#xff08;一&#xff09;显示 ln 命令的程序和 man 手册页的位置&#xff08;二&#xff09;显示 tomcat 相关文件的路径一、命令介绍 whereis 命令用来定位指令的二进制程序、源代码文件和man手册页等相关文件的路径。 wher…