{"id":334440,"date":"2022-06-14T09:00:58","date_gmt":"2022-06-14T09:00:58","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=334440"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=334440","title":{"rendered":"<span>\u041a\u0430\u043a \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e Spring Batch<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<div class=\"persona\" persona=\"true\"><img decoding=\"async\" persona=\"true\" class=\"image persona__image\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/142\/187\/781\/1421877818463c567cca4a30734e6852.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/142\/187\/781\/1421877818463c567cca4a30734e6852.png\"\/><\/p>\n<h5 class=\"persona__heading\" persona=\"true\">\u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u0422\u0440\u0438\u0448\u0435\u0447\u043a\u0438\u043d<\/h5>\n<p>\u0412\u0435\u0434\u0443\u0449\u0438\u0439 Java \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/p>\n<\/div>\n<p><strong><em>\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u0422\u0440\u0438\u0448\u0435\u0447\u043a\u0438\u043d, \u044f \u0432\u0435\u0434\u0443\u0449\u0438\u0439\u00a0Java\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0440\u043e\u0441\u0442\u043e\u0432\u0441\u043a\u043e\u0433\u043e \u043e\u0444\u0438\u0441\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438\u00a0Usetech. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e Spring Batch \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432. \u0421\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u043d\u0430 \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u044d\u0442\u043e\u0439 \u0441\u0440\u0435\u0434\u043e\u0439, \u043d\u043e \u043e\u043f\u044b\u0442\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 Spring Batch. \u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0451\u043c.<\/em><\/strong><\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435: <\/h2>\n<p><strong>Spring Batch<\/strong> \u2014 \u044d\u0442\u043e \u0441\u0440\u0435\u0434\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0431\u044a\u0451\u043c\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043e\u0441\u043d\u043e\u0432\u0435 Spring Batch \u043b\u0435\u0436\u0438\u0442 \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f (Job). \u041a\u0430\u0436\u0434\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044d\u0442\u0430\u043f\u043e\u0432 (Step). \u042d\u0442\u0430\u043f \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u0438\u0431\u043e \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 (Tasklet), \u043b\u0438\u0431\u043e \u0438\u043c\u0435\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u0438\u0437 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (ItemReader), \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (ItemProcessor) \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (ItemWriter).<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u0437\u0430\u0434\u0430\u0447\u0443 \u2014 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043e\u0442\u0447\u0451\u0442\u0430 \u043e \u043f\u0440\u043e\u0434\u0430\u0436\u0430\u0445 \u0438\u0437 csv \u0444\u0430\u0439\u043b\u0430 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0440\u0435\u0448\u0438\u043c, \u0447\u0442\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u043c \u043d\u0435 \u0432\u0430\u0436\u043d\u0430 \u0438 \u0444\u0430\u0439\u043b \u043e\u0442\u0447\u0451\u0442\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c. \u041f\u043e\u0434 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\u043c \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0448\u0430\u0433\u043e\u0432:<\/p>\n<ol>\n<li>\n<p>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u043e\u043a \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u043e\u0442\u0447\u0451\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0448\u0430\u0433 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043e\u0442\u0447\u0435\u0442\u0430 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0435\u0451 \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c (POJO), \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u0430\u0440\u043a\u0430\u0441\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f <a href=\"https:\/\/start.spring.io\/\">\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c<\/a>.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/316\/392\/3eb\/3163923ebca546961996fd409f574822.png\" width=\"1007\" height=\"843\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/316\/392\/3eb\/3163923ebca546961996fd409f574822.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 \u044d\u0442\u043e\u043c \u0436\u0435 \u043e\u043a\u043d\u0435 \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u043a\u0438:  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/020\/6b8\/598\/0206b8598efc8bdb6477f8ea73892d7a.png\" width=\"1008\" height=\"513\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/020\/6b8\/598\/0206b8598efc8bdb6477f8ea73892d7a.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>\u041a\u0430\u043a \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u044b\u0448\u0435, \u043a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043e\u0442\u0447\u0435\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432 Java \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <strong>SalesReportItem<\/strong> \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0435 \u0441\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c SpringBatchDemoApplication \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"java\">package ru.usetech.springbatchdemo; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; import java.math.BigDecimal; @Getter @Setter @AllArgsConstructor @NoArgsConstructor @ToString public class SalesReportItem { \/\/ \u0440\u0435\u0433\u0438\u043e\u043d private Long regionId; \/\/ \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u043e\u0434\u0430\u0436 private Long outletId; \/\/ \u0421\u0443\u043c\u043c\u0430 \u0432\u044b\u0440\u0443\u0447\u043a\u0438 \u043e\u0442 \u043f\u0440\u043e\u0434\u0430\u0436\u0438 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u043e\u0432, \u043a\u0430\u0440\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u043e\u0432 private BigDecimal smartphones; private BigDecimal memoryCards; private BigDecimal notebooks; \/\/ \u0421\u0443\u043c\u043c\u0430\u0440\u043d\u0430\u044f \u0432\u044b\u0440\u0443\u0447\u043a\u0430 \u043f\u043e \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0434\u0430\u0436 private BigDecimal total;  } <\/code><\/pre>\n<p>\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442 csv \u0444\u0430\u0439\u043b\u0430 \u043e\u0442\u0447\u0435\u0442\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<blockquote>\n<p>1|102|9589|4894|4955<\/p>\n<p>1|103|831|2637|126<\/p>\n<p>1|104|9343|963|3130<\/p>\n<\/blockquote>\n<p>\u00a0\u041f\u043e\u043b\u044f \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <strong>SalesReportItem<\/strong>:<\/p>\n<blockquote>\n<p>regionId|outletId|smartphones|memoryCards|notebooks<\/p>\n<\/blockquote>\n<p>\u0412\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0432 \u043e\u0442\u0447\u0451\u0442\u0435 \u043d\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u044f total, \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0434\u0430\u0436 \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430. \u0422\u0430\u043a\u0436\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0442\u0447\u0451\u0442\u0430\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u043c\u043c\u0430 \u0432\u044b\u0440\u0443\u0447\u043a\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u043e\u0439. \u041f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f <strong>IncorrectValueException<\/strong> \u0441 \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"java\">package ru.usetech.springbatchdemo; public class IncorrectValueException extends RuntimeException { } \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434: package ru.usetech.springbatchdemo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.configuration.annotation.StepScope; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.database.JdbcBatchItemWriter; import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; import org.springframework.batch.repeat.RepeatStatus; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; import java.math.BigDecimal; @Configuration @EnableBatchProcessing \/\/(1) public class BatchConfig { private static final Log log = LogFactory.getLog(BatchConfig.class); @Bean \/\/ (2) public Tasklet clearTableTasklet(JdbcTemplate jdbcTemplate) {         return (stepContribution, chunkContext) -> {             log.info(\"\u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b sales_report\");             jdbcTemplate.update(\"delete from sales_report\");             return RepeatStatus.FINISHED;         };     }  @Bean \/\/(3) public Step setupStep(Tasklet clearTableTasklet,                       StepBuilderFactory stepBuilderFactory) {         return stepBuilderFactory.get(\"clear-report-table\")             .tasklet(clearTableTasklet)             .build();     }  <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (4) public Step loadCsvStep(StepBuilderFactory stepBuilderFactory,                             FlatFileItemReader&lt;SalesReportItem> csvReader,                             ItemProcessor&lt;SalesReportItem, SalesReportItem> totalCalculatingProcessor,                         JdbcBatchItemWriter&lt;SalesReportItem> dbWriter) {         return stepBuilderFactory.get(\"load-csv-file\")             .&lt;SalesReportItem, SalesReportItem>chunk(10) \/\/ (5)             .faultTolerant()             .skip(IncorrectValueException.class) \/\/ (6)             .skipLimit(3) \/\/ (7)             .reader(csvReader) \/\/ (8)             .processor(totalCalculatingProcessor) \/\/ (9)             .writer(dbWriter) \/\/ (10)             .build();     } <\/code><\/pre>\n<pre><code class=\"java\">@Bean     @StepScope \/\/ (11) public FlatFileItemReader&lt;SalesReportItem> csvReader() {         return new FlatFileItemReaderBuilder&lt;SalesReportItem>().name(\"csv-reader\")             .resource(new ClassPathResource(\"report_data.csv\"))             .targetType(SalesReportItem.class)             .delimited()             .delimiter(\"|\")             .names(\"regionId\", \"outletId\", \"smartphones\", \"memoryCards\", \"notebooks\").build(); } <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (12) public ItemProcessor&lt;SalesReportItem, SalesReportItem> totalCalculatingProcessor() {     return item -> {         if (BigDecimal.ZERO.compareTo(item.getSmartphones()) > 0             || BigDecimal.ZERO.compareTo(item.getMemoryCards()) > 0             || BigDecimal.ZERO.compareTo(item.getNotebooks()) > 0) {             throw new IncorrectValueException();         }         item.setTotal(BigDecimal.ZERO.add(item.getSmartphones())                 .add(item.getMemoryCards()                         .add(item.getNotebooks())));         return item;     }; } <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (13) public JdbcBatchItemWriter&lt;SalesReportItem> dbWriter(DataSource dataSource) {     return new JdbcBatchItemWriterBuilder&lt;SalesReportItem>()             .dataSource(dataSource)             .sql(\"insert into sales_report (region_id, outlet_id, smartphones, memory_cards, notebooks, total) \" +                     \"values (:regionId, :outletId, :smartphones, :memoryCards, :notebooks, :total)\")             .beanMapped()             .build(); } <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (14) public Job importReportJob(JobBuilderFactory jobBuilderFactory,                            Step setupStep,                            Step loadCsvStep,                                ReportImportListener reportImportListener) {     return jobBuilderFactory.get(\"import-report-job\")             .incrementer(new RunIdIncrementer())             .listener(reportImportListener) \/\/ (15)             .start(setupStep)             .next(loadCsvStep)             .build(); }  } <\/code><\/pre>\n<p><strong>\u041c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b:<\/strong><\/p>\n<p><strong>(1)<\/strong> @EnableBatchProcessing \u2014 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f, \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u044e\u0449\u0430\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b Spring Batch, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 JobBuilderFactory \u0438 StepBuilderFactory, \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0440\u0435\u0435\u0441\u0442\u0440 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0438 \u043c\u043d\u043e\u0433\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.<\/p>\n<p><strong>(2)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0441\u043a\u043b\u0435\u0442\u0430, \u0442.\u0435. \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430. \u042d\u0442\u043e\u0442 \u043a\u043e\u0434, \u043a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043e\u0442\u0447\u0451\u0442\u0430.<\/p>\n<p><strong>(3)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0430\u0441\u043a\u043b\u0435\u0442\u0430.<\/p>\n<p><strong>(4)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0448\u0430\u0433\u0430, \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0447\u0451\u0442\u0430 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p><strong>(5)<\/strong> \u0417\u0434\u0435\u0441\u044c \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u0440\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a \u043e\u0442\u0447\u0451\u0442\u0430, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u0435\u043b\u0438\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u0441\u044f. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0440\u0446\u0438\u044f\u043c\u0438 \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u043f\u043e\u0440\u0446\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u044b\u043b\u0430 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u0430 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0448\u0435\u0439 \u043e\u0448\u0438\u0431\u043a\u0438, \u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0440\u0446\u0438\u0438.<\/p>\n<p><strong>(6) \u2014 (7)<\/strong> \u042d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u043e\u0442\u0447\u0451\u0442\u0430, \u0437\u0430\u0434\u0430\u0451\u043c, \u0447\u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 IncorrectValueException, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u043f\u0430\u0434\u0435\u043d\u0438\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u043e \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u0442\u0440\u0451\u0445 \u0440\u0430\u0437.\u00a0<\/p>\n<p><strong>(8) \u2014 (10)<\/strong> \u0417\u0430\u0434\u0430\u0451\u043c \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0411\u0414.<\/p>\n<p><strong>(11)<\/strong> \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u0443\u0442 \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c FlatFileItemReader \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Spring Batch. \u0412 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0438\u00a0 Spring Batch \u0432\u0445\u043e\u0434\u0438\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u0432 \u0411\u0414, \u0438\u0437 JSON \u0444\u0430\u0439\u043b\u043e\u0432, \u0438\u0437 \u0442\u043e\u043f\u0438\u043a\u043e\u0432 Kafka \u0438 \u0434\u0440. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u044c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ItemReader.<\/p>\n<p><strong>(12)<\/strong> \u041f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ItemProcessor. \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u0443\u044e \u0432\u044b\u0440\u0443\u0447\u043a\u0443 \u043f\u043e \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0434\u0430\u0436.\u00a0<\/p>\n<p><strong>(13)<\/strong> \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 POJO \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.\u00a0<\/p>\n<p><strong>(14)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u044f (Job), \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u0432\u0443\u0445 \u0448\u0430\u0433\u043e\u0432.<\/p>\n<p><strong>(15)<\/strong> \u0421\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044c, \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u044d\u0442\u0430\u043f\u044b \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043d\u0438\u0436\u0435:  <\/p>\n<pre><code class=\"java\">package ru.usetech.springbatchdemo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.listener.JobExecutionListenerSupport; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service;  @Service public class ReportImportListener extends JobExecutionListenerSupport {  private static final Log log = LogFactory.getLog(ReportImportListener.class);  private final JdbcTemplate jdbcTemplate;  public ReportImportListener(JdbcTemplate jdbcTemplate) {         this.jdbcTemplate = jdbcTemplate;     }  @Override public void afterJob(JobExecution jobExecution) {         if(jobExecution.getStatus() == BatchStatus.COMPLETED) {             log.info(\"\u041e\u0442\u0447\u0451\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445\");             logAll();         }     }  @Override public void beforeJob(JobExecution jobExecution) {         log.info(\"\u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430\");         logAll();     }  private void logAll() {         jdbcTemplate.query(\"SELECT region_id, outlet_id, smartphones, memory_cards, notebooks, total FROM sales_report\",             (rs, row) -> new SalesReportItem(                     rs.getLong(1),                     rs.getLong(2),                     rs.getBigDecimal(3),                     rs.getBigDecimal(4),                     rs.getBigDecimal(5),                     rs.getBigDecimal(6))         ).forEach(log::info);     }  } <\/code><\/pre>\n<p>\u0421\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <strong>\u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430<\/strong>:<\/p>\n<ol>\n<li>\n<p>beforeJob \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u0447\u0451\u0442\u0430 \u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>afterJob \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0438 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u0447\u0451\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0448\u0435\u0433\u043e Spring Batch \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ab2\/ad1\/dd6\/ab2ad1dd6e5723ebe20304b32a4f6560.png\" width=\"614\" height=\"495\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ab2\/ad1\/dd6\/ab2ad1dd6e5723ebe20304b32a4f6560.png\"\/><figcaption><\/figcaption><\/figure>\n<p>application.yml \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a in memory \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445:  <\/p>\n<pre><code class=\"java\">spring:   datasource: url: jdbc:h2:mem:mydb username: sales password: sales driverClassName: org.h2.Driver<\/code><\/pre>\n<p>schema-all.sql \u2014 \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u0447\u0435\u0442\u0430 sales_report:<\/p>\n<pre><code class=\"java\">CREATE TABLE IF NOT EXISTS sales_report (     region_id BIGINT,     outlet_id BIGINT,     smartphones NUMBER,     memory_cards NUMBER,     notebooks NUMBER,     total NUMBER );<\/code><\/pre>\n<p>data.sql \u2014 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u0447\u0451\u0442\u0430 (\u0434\u043b\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430):<\/p>\n<p><strong>insert into <\/strong>sales_report (<em>region_id<\/em>, <em>outlet_id<\/em>, <em>smartphones<\/em>, <em>memory_cards<\/em>, <em>notebooks<\/em>, <em>total<\/em>)\u00a0 <strong>values <\/strong>(1, 121, 2365, 4377, 9256, 15998);<\/p>\n<p><strong>insert into <\/strong>sales_report (<em>region_id<\/em>, <em>outlet_id<\/em>, <em>smartphones<\/em>, <em>memory_cards<\/em>, <em>notebooks<\/em>, <em>total<\/em>)\u00a0 <strong>values <\/strong>(1, 122, 9589, 4894, 4955, 19438);<\/p>\n<p><strong>insert into <\/strong>sales_report (<em>region_id<\/em>, <em>outlet_id<\/em>, <em>smartphones<\/em>, <em>memory_cards<\/em>, <em>notebooks<\/em>, <em>total<\/em>)\u00a0 <strong>values <\/strong>(2, 233, 6836, 5318, 9563, 21717);<\/p>\n<p>report_data.csv \u2014 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u043e\u0442\u0447\u0451\u0442\u0430:  <\/p>\n<blockquote>\n<p>1|101|2365|4377|-9256<\/p>\n<p>1|102|9589|4894|4955<\/p>\n<p>1|103|831|2637|126<\/p>\n<p>1|104|9343|963|3130<\/p>\n<p>1|105|8764|2605|985<\/p>\n<p>1|106|4886|2789|5797<\/p>\n<p>1|107|8201|9634|291<\/p>\n<p>1|108|3287|-4926|2015<\/p>\n<p>1|109|5411|9759|8777<\/p>\n<p>1|110|2092|52|8092<\/p>\n<p>2|201|4933|1308|4011<\/p>\n<p>2|202|7868|2806|3763<\/p>\n<p>2|203|6836|5318|9563<\/p>\n<p>2|204|5085|-675|5987<\/p>\n<p>2|205|7362|4139|5800<\/p>\n<p>2|206|4729|554|7194<\/p>\n<p>2|207|4112|3782|8052<\/p>\n<p>2|208|4146|5560|2037<\/p>\n<p>2|209|8435|2201|4973<\/p>\n<p>2|210|1424|9298|4993<\/p>\n<\/blockquote>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0442\u0440\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0451 \u0433\u043e\u0442\u043e\u0432\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448\u0435 Spring Boot \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0435\u0433\u043e \u0432 IDE \u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0432 \u043b\u043e\u0433\u0435:<\/p>\n<blockquote>\n<p>2022-04-29 01:28:14.066\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.b.a.b.JobLauncherApplicationRunner \u00a0 : Running default command line with: []<\/p>\n<p>2022-04-29 01:28:14.112\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.b.c.l.support.SimpleJobLauncher\u00a0 \u00a0 \u00a0 : Job: [SimpleJob: [name=import-report-job]] launched with the following parameters: [{run.id=1}]<\/p>\n<p>2022-04-29 01:28:14.127\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : \u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430<\/p>\n<p>2022-04-29 01:28:14.147\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=121, smartphones=2365, memoryCards=4377, notebooks=9256, total=15998)<\/p>\n<p>2022-04-29 01:28:14.147\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=122, smartphones=9589, memoryCards=4894, notebooks=4955, total=19438)<\/p>\n<p>2022-04-29 01:28:14.147\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=233, smartphones=6836, memoryCards=5318, notebooks=9563, total=21717)<\/p>\n<p>2022-04-29 01:28:14.153\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.job.SimpleStepHandler \u00a0 \u00a0 : Executing step: [clear-report-table]<\/p>\n<p>2022-04-29 01:28:14.162\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] ru.usetech.springbatchdemo.BatchConfig \u00a0 : \u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b sales_report<\/p>\n<p>2022-04-29 01:28:14.169\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.step.AbstractStep \u00a0 \u00a0 \u00a0 \u00a0 : Step: [clear-report-table] executed in 16ms<\/p>\n<p>2022-04-29 01:28:14.176\u00a0 INFO 7381 &#8212; [\u00a0 \u00a0  \u00a0 main] o.s.batch.core.job.SimpleStepHandler \u00a0 \u00a0 : Executing step: [load-csv-file]<\/p>\n<p>2022-04-29 01:28:14.244\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.step.AbstractStep \u00a0 \u00a0 \u00a0 \u00a0 : Step: [load-csv-file] executed in 68ms<\/p>\n<p>2022-04-29 01:28:14.247\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : \u041e\u0442\u0447\u0451\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=102, smartphones=9589, memoryCards=4894, notebooks=4955, total=19438)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=103, smartphones=831, memoryCards=2637, notebooks=126, total=3594)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=104, smartphones=9343, memoryCards=963, notebooks=3130, total=13436)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [\u00a0 \u00a0 \u00a0  main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=105, smartphones=8764, memoryCards=2605, notebooks=985, total=12354)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=106, smartphones=4886, memoryCards=2789, notebooks=5797, total=13472)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=107, smartphones=8201, memoryCards=9634, notebooks=291, total=18126)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=109, smartphones=5411, memoryCards=9759, notebooks=8777, total=23947)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=110, smartphones=2092, memoryCards=52, notebooks=8092, total=10236)<\/p>\n<p>2022-04-29 01:28:14.249\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=201, smartphones=4933, memoryCards=1308, notebooks=4011, total=10252)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=202, smartphones=7868, memoryCards=2806, notebooks=3763, total=14437)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=203, smartphones=6836, memoryCards=5318, notebooks=9563, total=21717)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=205, smartphones=7362, memoryCards=4139, notebooks=5800, total=17301)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=206, smartphones=4729, memoryCards=554, notebooks=7194, total=12477)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=207, smartphones=4112, memoryCards=3782, notebooks=8052, total=15946)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=208, smartphones=4146, memoryCards=5560, notebooks=2037, total=11743)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=209, smartphones=8435, memoryCards=2201, notebooks=4973, total=15609)<\/p>\n<p>2022-04-29 01:28:14.250\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=210, smartphones=1424, memoryCards=9298, notebooks=4993, total=15715)<\/p>\n<p>2022-04-29 01:28:14.252\u00a0 INFO 7381 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.b.c.l.support.SimpleJobLauncher\u00a0 \u00a0 \u00a0 : Job: [SimpleJob: [name=import-report-job]] completed with the following parameters: [{run.id=1}] and the following status: [COMPLETED] in 125ms<\/p>\n<\/blockquote>\n<p>\u0412 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u0445 \u043b\u043e\u0433\u0430 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0441\u0442\u0430\u0440\u0442\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 sales_report \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u0430 3 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e \u0442\u043e\u0447\u043a\u0430\u043c \u043f\u0440\u043e\u0434\u0430\u0436 121, 122 \u0438 233. \u0414\u0430\u043b\u0435\u0435 \u0431\u044b\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0442\u0447\u0451\u0442\u0430 \u0438 \u0431\u044b\u043b\u043e \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u0447\u0451\u0442\u0430 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0412\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0442\u043e\u0447\u043a\u0430\u043c 121, 122 \u0438 233 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0442\u043e\u0447\u043a\u0430\u043c 101, 108 \u0438 204, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043d\u0435 \u0431\u044b\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a \u0431\u044b\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0440\u0451\u0445 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0441\u043d\u043e\u0432\u0430.<\/p>\n<blockquote>\n<p>2022-04-29 01:29:11.070\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.b.a.b.JobLauncherApplicationRunner \u00a0 : Running default command line with: []<\/p>\n<p>2022-04-29 01:29:11.114\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.b.c.l.support.SimpleJobLauncher\u00a0 : Job: [SimpleJob: [name=import-report-job]] launched with the following parameters: [{run.id=1}]<\/p>\n<p>2022-04-29 01:29:11.128\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : \u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430<\/p>\n<p>2022-04-29 01:29:11.149\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=121, smartphones=2365, memoryCards=4377, notebooks=9256, total=15998)<\/p>\n<p>2022-04-29 01:29:11.149\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=1, outletId=122, smartphones=9589, memoryCards=4894, notebooks=4955, total=19438)<\/p>\n<p>2022-04-29 01:29:11.149\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] r.u.s.ReportImportListener \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : SalesReportItem(regionId=2, outletId=233, smartphones=6836, memoryCards=5318, notebooks=9563, total=21717)<\/p>\n<p>2022-04-29 01:29:11.156\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.job.SimpleStepHandler \u00a0 \u00a0 : Executing step: [clear-report-table]<\/p>\n<p>2022-04-29 01:29:11.164\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] ru.usetech.springbatchdemo.BatchConfig \u00a0 : \u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b sales_report<\/p>\n<p>2022-04-29 01:29:11.170\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.step.AbstractStep \u00a0 \u00a0 \u00a0 \u00a0 : Step: [clear-report-table] executed in 14ms<\/p>\n<p>2022-04-29 01:29:11.177\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.job.SimpleStepHandler \u00a0 \u00a0 : Executing step: [load-csv-file]<\/p>\n<p>2022-04-29 01:29:11.241 ERROR 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.step.AbstractStep \u00a0 \u00a0 : Encountered an error executing step load-csv-file in job import-report-job<\/p>\n<p>\u00a0<\/p>\n<p>org.springframework.batch.core.step.skip.SkipLimitExceededException: Skip limit of &#8216;3&#8217; exceeded<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy.shouldSkip(LimitCheckingItemSkipPolicy.java:133) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.skip.ExceptionClassifierSkipPolicy.shouldSkip(ExceptionClassifierSkipPolicy.java:70) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.shouldSkip(FaultTolerantChunkProcessor.java:519) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.access$500(FaultTolerantChunkProcessor.java:56) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$2.recover(FaultTolerantChunkProcessor.java:289) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:539) ~[spring-retry-1.3.3.jar:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:387) ~[spring-retry-1.3.3.jar:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:255) ~[spring-retry-1.3.3.jar:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:217) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.transform(FaultTolerantChunkProcessor.java:308) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:210) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:77) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.19.jar:5.3.19]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:413) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:149) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.3.19.jar:5.3.19]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at java.base\/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at java.base\/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at java.base\/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at java.base\/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.19.jar:5.3.19]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.19.jar:5.3.19]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.19.jar:5.3.19]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.19.jar:5.3.19]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.19.jar:5.3.19]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at com.sun.proxy.$Proxy54.run(Unknown Source) ~[na:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199) ~[spring-boot-autoconfigure-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173) ~[spring-boot-autoconfigure-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160) ~[spring-boot-autoconfigure-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155) ~[spring-boot-autoconfigure-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150) ~[spring-boot-autoconfigure-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:768) ~[spring-boot-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:758) ~[spring-boot-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.7.jar:2.6.7]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at ru.usetech.springbatchdemo.SpringBatchDemoApplication.main(SpringBatchDemoApplication.java:10) ~[classes\/:na]<\/p>\n<p>Caused by: ru.usetech.springbatchdemo.IncorrectValueException: null<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at ru.usetech.springbatchdemo.BatchConfig.lambda$totalCalculatingProcessor$1(BatchConfig.java:84) ~[classes\/:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:134) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$1.doWithRetry(FaultTolerantChunkProcessor.java:239) ~[spring-batch-core-4.3.5.jar:4.3.5]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) ~[spring-retry-1.3.3.jar:na]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8230; 44 common frames omitted<\/p>\n<p>2022-04-29 01:29:11.243\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.batch.core.step.AbstractStep \u00a0 \u00a0 : Step: [load-csv-file] executed in 66ms<\/p>\n<p>2022-04-29 01:29:11.249\u00a0 INFO 7482 &#8212; [ \u00a0 \u00a0 \u00a0 main] o.s.b.c.l.support.SimpleJobLauncher\u00a0 \u00a0 \u00a0 : Job: [SimpleJob: [name=import-report-job]] completed with the following parameters: [{run.id=1}] and the following status: [FAILED] in 124ms<\/p>\n<\/blockquote>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 Skip limit of &#8216;3&#8217; exceeded, \u0447\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u043e\u0441\u043d\u043e\u0432\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f Spring Batch \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430. \u041c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u0439, \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438, \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a \u0437\u0430\u0434\u0430\u043d\u0438\u0439, \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 bpm \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0438 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044f.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/usetech\/blog\/671196\/\"> https:\/\/habr.com\/ru\/company\/usetech\/blog\/671196\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<div class=\"persona\" persona=\"true\">\n<h5 class=\"persona__heading\" persona=\"true\">\u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u0422\u0440\u0438\u0448\u0435\u0447\u043a\u0438\u043d<\/h5>\n<p>\u0412\u0435\u0434\u0443\u0449\u0438\u0439 Java \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/p>\n<\/div>\n<p><strong><em>\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u0422\u0440\u0438\u0448\u0435\u0447\u043a\u0438\u043d, \u044f \u0432\u0435\u0434\u0443\u0449\u0438\u0439\u00a0Java\u00a0\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0440\u043e\u0441\u0442\u043e\u0432\u0441\u043a\u043e\u0433\u043e \u043e\u0444\u0438\u0441\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438\u00a0Usetech. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e Spring Batch \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432. \u0421\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u043d\u0430 \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u044d\u0442\u043e\u0439 \u0441\u0440\u0435\u0434\u043e\u0439, \u043d\u043e \u043e\u043f\u044b\u0442\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 Spring Batch. \u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0451\u043c.<\/em><\/strong><\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435: <\/h2>\n<p><strong>Spring Batch<\/strong> \u2014 \u044d\u0442\u043e \u0441\u0440\u0435\u0434\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0431\u044a\u0451\u043c\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043e\u0441\u043d\u043e\u0432\u0435 Spring Batch \u043b\u0435\u0436\u0438\u0442 \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f (Job). \u041a\u0430\u0436\u0434\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044d\u0442\u0430\u043f\u043e\u0432 (Step). \u042d\u0442\u0430\u043f \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u0438\u0431\u043e \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 (Tasklet), \u043b\u0438\u0431\u043e \u0438\u043c\u0435\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u0438\u0437 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (ItemReader), \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (ItemProcessor) \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (ItemWriter).<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u0437\u0430\u0434\u0430\u0447\u0443 \u2014 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043e\u0442\u0447\u0451\u0442\u0430 \u043e \u043f\u0440\u043e\u0434\u0430\u0436\u0430\u0445 \u0438\u0437 csv \u0444\u0430\u0439\u043b\u0430 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0440\u0435\u0448\u0438\u043c, \u0447\u0442\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u043c \u043d\u0435 \u0432\u0430\u0436\u043d\u0430 \u0438 \u0444\u0430\u0439\u043b \u043e\u0442\u0447\u0451\u0442\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c. \u041f\u043e\u0434 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\u043c \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0448\u0430\u0433\u043e\u0432:<\/p>\n<ol>\n<li>\n<p>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u043e\u043a \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u043e\u0442\u0447\u0451\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0448\u0430\u0433 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043e\u0442\u0447\u0435\u0442\u0430 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0435\u0451 \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c (POJO), \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u0430\u0440\u043a\u0430\u0441\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f <a href=\"https:\/\/start.spring.io\/\">\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c<\/a>.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 \u044d\u0442\u043e\u043c \u0436\u0435 \u043e\u043a\u043d\u0435 \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u043a\u0438:  <\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>\u041a\u0430\u043a \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u044b\u0448\u0435, \u043a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043e\u0442\u0447\u0435\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432 Java \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <strong>SalesReportItem<\/strong> \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0435 \u0441\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c SpringBatchDemoApplication \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"java\">package ru.usetech.springbatchdemo; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; import java.math.BigDecimal; @Getter @Setter @AllArgsConstructor @NoArgsConstructor @ToString public class SalesReportItem { \/\/ \u0440\u0435\u0433\u0438\u043e\u043d private Long regionId; \/\/ \u0442\u043e\u0447\u043a\u0430 \u043f\u0440\u043e\u0434\u0430\u0436 private Long outletId; \/\/ \u0421\u0443\u043c\u043c\u0430 \u0432\u044b\u0440\u0443\u0447\u043a\u0438 \u043e\u0442 \u043f\u0440\u043e\u0434\u0430\u0436\u0438 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u043e\u0432, \u043a\u0430\u0440\u0442 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u043e\u0432 private BigDecimal smartphones; private BigDecimal memoryCards; private BigDecimal notebooks; \/\/ \u0421\u0443\u043c\u043c\u0430\u0440\u043d\u0430\u044f \u0432\u044b\u0440\u0443\u0447\u043a\u0430 \u043f\u043e \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0434\u0430\u0436 private BigDecimal total;  } <\/code><\/pre>\n<p>\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442 csv \u0444\u0430\u0439\u043b\u0430 \u043e\u0442\u0447\u0435\u0442\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<blockquote>\n<p>1|102|9589|4894|4955<\/p>\n<p>1|103|831|2637|126<\/p>\n<p>1|104|9343|963|3130<\/p>\n<\/blockquote>\n<p>\u00a0\u041f\u043e\u043b\u044f \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <strong>SalesReportItem<\/strong>:<\/p>\n<blockquote>\n<p>regionId|outletId|smartphones|memoryCards|notebooks<\/p>\n<\/blockquote>\n<p>\u0412\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0432 \u043e\u0442\u0447\u0451\u0442\u0435 \u043d\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u044f total, \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0434\u0430\u0436 \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043c \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430. \u0422\u0430\u043a\u0436\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0442\u0447\u0451\u0442\u0430\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u043c\u043c\u0430 \u0432\u044b\u0440\u0443\u0447\u043a\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u043e\u0439. \u041f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f <strong>IncorrectValueException<\/strong> \u0441 \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"java\">package ru.usetech.springbatchdemo; public class IncorrectValueException extends RuntimeException { } \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434: package ru.usetech.springbatchdemo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.configuration.annotation.StepScope; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.database.JdbcBatchItemWriter; import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; import org.springframework.batch.repeat.RepeatStatus; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; import java.math.BigDecimal; @Configuration @EnableBatchProcessing \/\/(1) public class BatchConfig { private static final Log log = LogFactory.getLog(BatchConfig.class); @Bean \/\/ (2) public Tasklet clearTableTasklet(JdbcTemplate jdbcTemplate) {         return (stepContribution, chunkContext) -> {             log.info(\"\u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b sales_report\");             jdbcTemplate.update(\"delete from sales_report\");             return RepeatStatus.FINISHED;         };     }  @Bean \/\/(3) public Step setupStep(Tasklet clearTableTasklet,                       StepBuilderFactory stepBuilderFactory) {         return stepBuilderFactory.get(\"clear-report-table\")             .tasklet(clearTableTasklet)             .build();     }  <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (4) public Step loadCsvStep(StepBuilderFactory stepBuilderFactory,                             FlatFileItemReader&lt;SalesReportItem> csvReader,                             ItemProcessor&lt;SalesReportItem, SalesReportItem> totalCalculatingProcessor,                         JdbcBatchItemWriter&lt;SalesReportItem> dbWriter) {         return stepBuilderFactory.get(\"load-csv-file\")             .&lt;SalesReportItem, SalesReportItem>chunk(10) \/\/ (5)             .faultTolerant()             .skip(IncorrectValueException.class) \/\/ (6)             .skipLimit(3) \/\/ (7)             .reader(csvReader) \/\/ (8)             .processor(totalCalculatingProcessor) \/\/ (9)             .writer(dbWriter) \/\/ (10)             .build();     } <\/code><\/pre>\n<pre><code class=\"java\">@Bean     @StepScope \/\/ (11) public FlatFileItemReader&lt;SalesReportItem> csvReader() {         return new FlatFileItemReaderBuilder&lt;SalesReportItem>().name(\"csv-reader\")             .resource(new ClassPathResource(\"report_data.csv\"))             .targetType(SalesReportItem.class)             .delimited()             .delimiter(\"|\")             .names(\"regionId\", \"outletId\", \"smartphones\", \"memoryCards\", \"notebooks\").build(); } <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (12) public ItemProcessor&lt;SalesReportItem, SalesReportItem> totalCalculatingProcessor() {     return item -> {         if (BigDecimal.ZERO.compareTo(item.getSmartphones()) > 0             || BigDecimal.ZERO.compareTo(item.getMemoryCards()) > 0             || BigDecimal.ZERO.compareTo(item.getNotebooks()) > 0) {             throw new IncorrectValueException();         }         item.setTotal(BigDecimal.ZERO.add(item.getSmartphones())                 .add(item.getMemoryCards()                         .add(item.getNotebooks())));         return item;     }; } <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (13) public JdbcBatchItemWriter&lt;SalesReportItem> dbWriter(DataSource dataSource) {     return new JdbcBatchItemWriterBuilder&lt;SalesReportItem>()             .dataSource(dataSource)             .sql(\"insert into sales_report (region_id, outlet_id, smartphones, memory_cards, notebooks, total) \" +                     \"values (:regionId, :outletId, :smartphones, :memoryCards, :notebooks, :total)\")             .beanMapped()             .build(); } <\/code><\/pre>\n<pre><code class=\"java\">@Bean \/\/ (14) public Job importReportJob(JobBuilderFactory jobBuilderFactory,                            Step setupStep,                            Step loadCsvStep,                                ReportImportListener reportImportListener) {     return jobBuilderFactory.get(\"import-report-job\")             .incrementer(new RunIdIncrementer())             .listener(reportImportListener) \/\/ (15)             .start(setupStep)             .next(loadCsvStep)             .build(); }  } <\/code><\/pre>\n<p><strong>\u041c\u0430\u0440\u043a\u0435\u0440\u0430\u043c\u0438 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b:<\/strong><\/p>\n<p><strong>(1)<\/strong> @EnableBatchProcessing \u2014 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f, \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u044e\u0449\u0430\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b Spring Batch, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 JobBuilderFactory \u0438 StepBuilderFactory, \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0440\u0435\u0435\u0441\u0442\u0440 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0438 \u043c\u043d\u043e\u0433\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.<\/p>\n<p><strong>(2)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0441\u043a\u043b\u0435\u0442\u0430, \u0442.\u0435. \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430. \u042d\u0442\u043e\u0442 \u043a\u043e\u0434, \u043a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043e\u0442\u0447\u0451\u0442\u0430.<\/p>\n<p><strong>(3)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0430\u0441\u043a\u043b\u0435\u0442\u0430.<\/p>\n<p><strong>(4)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0448\u0430\u0433\u0430, \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0447\u0451\u0442\u0430 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p><strong>(5)<\/strong> \u0417\u0434\u0435\u0441\u044c \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u0440\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a \u043e\u0442\u0447\u0451\u0442\u0430, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u0435\u043b\u0438\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u0441\u044f. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0440\u0446\u0438\u044f\u043c\u0438 \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u043f\u043e\u0440\u0446\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0442\u0447\u0451\u0442\u0430 \u0431\u044b\u043b\u0430 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u0430 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0448\u0435\u0439 \u043e\u0448\u0438\u0431\u043a\u0438, \u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u043f\u043e\u0441\u043b\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0440\u0446\u0438\u0438.<\/p>\n<p><strong>(6) \u2014 (7)<\/strong> \u042d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u043e\u0442\u0447\u0451\u0442\u0430, \u0437\u0430\u0434\u0430\u0451\u043c, \u0447\u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 IncorrectValueException, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u043f\u0430\u0434\u0435\u043d\u0438\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0447\u0451\u0442\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u043e \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u0442\u0440\u0451\u0445 \u0440\u0430\u0437.\u00a0<\/p>\n<p><strong>(8) \u2014 (10)<\/strong> \u0417\u0430\u0434\u0430\u0451\u043c \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0411\u0414.<\/p>\n<p><strong>(11)<\/strong> \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u0443\u0442 \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c FlatFileItemReader \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Spring Batch. \u0412 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0438\u00a0 Spring Batch \u0432\u0445\u043e\u0434\u0438\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u0432 \u0411\u0414, \u0438\u0437 JSON \u0444\u0430\u0439\u043b\u043e\u0432, \u0438\u0437 \u0442\u043e\u043f\u0438\u043a\u043e\u0432 Kafka \u0438 \u0434\u0440. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u0435\u043b\u044c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ItemReader.<\/p>\n<p><strong>(12)<\/strong> \u041f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ItemProcessor. \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u0443\u044e \u0432\u044b\u0440\u0443\u0447\u043a\u0443 \u043f\u043e \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u043e\u0434\u0430\u0436.\u00a0<\/p>\n<p><strong>(13)<\/strong> \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 POJO \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.\u00a0<\/p>\n<p><strong>(14)<\/strong> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-334440","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334440","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=334440"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334440\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=334440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=334440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=334440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}