最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBatch結(jié)合SpringBoot簡單使用實(shí)現(xiàn)工資發(fā)放批處理操作方式

 更新時(shí)間:2023年09月11日 15:59:56   作者:回爐重造P  
這篇文章主要介紹了SpringBatch結(jié)合SpringBoot簡單使用實(shí)現(xiàn)工資發(fā)放批處理操作方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

最近有接觸到批處理相關(guān)的需求,學(xué)習(xí)了下SpringBatch的使用方法。SpringBatch能把復(fù)雜的批處理任務(wù)進(jìn)行step分解,并能通過reader和writer滿足不同來源數(shù)據(jù)的處理需求,支持在step定義時(shí)設(shè)置異常重試策略等,比較方便拓展。

簡單記錄下基于SpringBoot寫的使用demo。

需求

兩張表,user_with_role和role_num,分別有user信息和工資流水信息,role_num冗余。

user_with_role表,包含員工信息和role字段信息

CREATE TABLE `user_with_role` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(45) NULL,
  `role` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));

role_num表,包含發(fā)錢信息

CREATE TABLE `role_num1` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `role` VARCHAR(45) NULL,
  `account` INT NULL,
  `username` VARCHAR(45) NULL,
  `inputtime` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));

pom設(shè)置和application配置文件

在springboot的基礎(chǔ)上使用batch,pom.xml中增加dependency

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>

還需要加上jdbc依賴,不過這個(gè)一般都有加。

application中增加:

spring:
  batch:
    initialize-schema: always

這個(gè)配置主要是讓springbatch自動在數(shù)據(jù)庫中創(chuàng)建運(yùn)行所需的表,SpringBoot2.7版本后修改為 spring.batch.jdbc.initialize-schema 了,不過我還在用老土2.3,先這樣吧。

bean類

UserWithRole

@Data
public class UserWithRole {
    private int id;
    private String userName;
	private String role;
}

RoleNum

@Data
public class RoleNum {
    private int id;
    private String role;
    private int account;
    private String userName;
	private String inputTime;
}

關(guān)鍵job配置類

包含reader,writer,step和整體job的配置,通過@Bean注解的方法來進(jìn)行spring管理,下面一步步來。

@Configuration
@EnableBatchProcessing
// batch job設(shè)置
// 將user_with_role中的role_user工資信息,輸出到role_num表中
public class RoleCountingBatchJobConfig {
    //注入任務(wù)對象工廠
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    //任務(wù)的執(zhí)行由Step決定,注入step對象的factory
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

SpringBatch默認(rèn)會構(gòu)建兩個(gè)Factory用來進(jìn)行job構(gòu)建,DataSource默認(rèn)為Spring配置的數(shù)據(jù)庫,NamedParameterJdbcTemplate由Spring提供,用來將statement中的問號占位符改為利用命名參數(shù)映射更方便,不過我后面沒用。

    // 設(shè)置itemReader
    @Bean
    public JdbcCursorItemReader<UserWithRole> getItemReader(){
        JdbcCursorItemReader<UserWithRole> itemReader = new JdbcCursorItemReader<>();
        itemReader.setDataSource(dataSource);//設(shè)置數(shù)據(jù)源
        // 實(shí)體映射
        itemReader.setRowMapper(new RowMapper<UserWithRole>() {
            @Override
            public UserWithRole mapRow(ResultSet rs, int rowNum) throws SQLException {
                UserWithRole uwr = new UserWithRole();
                uwr.setId(rs.getInt("id"));
                uwr.setUserName(rs.getString("userName"));
                uwr.setRole(rs.getString("role"));
                return uwr;
            }
        });
        String sql = "select u.id as id, u.username as userName, u.role as role from user_with_role as u";
        itemReader.setSql(sql);
        return itemReader;
    }

itemReader 用的是 JdbcCursorItemReader ,用來從user_with_role表中讀取數(shù)據(jù),主要是配置 RowMapper ,將行數(shù)據(jù)封裝成 UserWithRole 對象,sql就是簡單查詢。

    // 設(shè)置itemWriter
    @Bean
    public JdbcBatchItemWriter<RoleNum> getItemWriter(){
        JdbcBatchItemWriter<RoleNum> itemWriter = new JdbcBatchItemWriter<>();
        itemWriter.setDataSource(dataSource);
        itemWriter.setJdbcTemplate(namedParameterJdbcTemplate);
        String sql = "insert into role_num(role, account, username, inputtime) values(?, ?, ?, ?)";
        itemWriter.setSql(sql);
        itemWriter.setItemPreparedStatementSetter(new RoleNumPreparedStatementSetter());
        return itemWriter;
    }

itemWriter 用的是 JdbcBatchItemWriter ,用來把RoleNum對象存到數(shù)據(jù)庫中,主要的參數(shù)寫入邏輯寫在 RoleNumPreparedStatementSetter 類中。

public class RoleNumPreparedStatementSetter implements ItemPreparedStatementSetter<RoleNum> {
    // 將role_num的批處理計(jì)算結(jié)果存入的sql
    @Override
    public void setValues(RoleNum roleNum, PreparedStatement preparedStatement) throws SQLException {
        preparedStatement.setString(1, roleNum.getRole());
        preparedStatement.setInt(2, roleNum.getAccount());
        preparedStatement.setString(3, roleNum.getUserName());
        preparedStatement.setString(4, roleNum.getInputTime());
    }
}

RoleNumPreparedStatementSetter 主要是將參數(shù)通過占位符放到sql中。

    // 設(shè)置process
    @Bean
    public RoleUserCountingProcess getProcess(){
        return new RoleUserCountingProcess();
    }
public class RoleUserCountingProcess implements ItemProcessor<UserWithRole, RoleNum> {
    // 將user的信息轉(zhuǎn)換成roleNum信息,當(dāng)作發(fā)工資
    @Override
    public RoleNum process(UserWithRole userWithRole) throws Exception {
        RoleNum newRoleNum = new RoleNum();
        newRoleNum.setUserName(userWithRole.getUserName());
        newRoleNum.setRole(userWithRole.getRole());
        newRoleNum.setInputTime(new LocalDateTime(new Date()).toString());
        if(userWithRole.getRole()==null)
            return newRoleNum;
        switch (userWithRole.getRole()) {
            case "employee":
                newRoleNum.setAccount(100);
                break;
            case "manager":
                newRoleNum.setAccount(10000);
                break;
            case "boss":
                newRoleNum.setAccount(100000);
                break;
        }
        System.out.println(newRoleNum.getUserName() + "---" + newRoleNum.getAccount());
        return newRoleNum;
    }
}

process中定義了具體的工資寫入邏輯,實(shí)現(xiàn)了 ItemProcess 接口的process方法,將itemReader的輸出UserWithRole類和itemWriter的輸入RoleNum類進(jìn)行連接,從而完成process過程。

    // 設(shè)置step
    @Bean
    public Step getStep(){
        return stepBuilderFactory.get("user_role_convert_step")
                .<UserWithRole, RoleNum>chunk(10)
                .reader(getItemReader())
                .processor(getProcess())
                .writer(getItemWriter())
                .build();
    }
    // 獲取job對象
    @Bean
    public Job RoleCountingBatchJob(JobBuilderFactory jobBuilders,
                                    StepBuilderFactory stepBuilders){
        return jobBuilders.get("user_role_convert_step")
                .start(getStep())
                .build();
    }

最后定義step和job整體流程。

在配置文件中加入:

spring:
  batch:
    job:
      enabled: false

可以阻止job在項(xiàng)目啟動時(shí)自動執(zhí)行。

controller啟動jobInstance

@Controller
public class BatchRunnerController {
    @Autowired
    JobLauncher jobLauncher;
    // 自定義job任務(wù)
    @Autowired
    Job roleCountingBatchJob;
    @RequestMapping("/countingRoleUser")
    @ResponseBody
    public String countingRollUser() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
        // 設(shè)置時(shí)間parameter來區(qū)分instance
        JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addDate("startDate", new Date());
        jobLauncher.run(roleCountingBatchJob, jobParametersBuilder.toJobParameters());
        return "role user counting batch success --- " +
                Objects.requireNonNull(jobParametersBuilder.toJobParameters().getDate("startDate")).toString();
    }
}

利用 jobLauncher 來執(zhí)行對應(yīng)的job,date時(shí)間來區(qū)分不同的jobInstance。

實(shí)現(xiàn)效果

在這里插入圖片描述

user_with_role表

在這里插入圖片描述

批處理job正常執(zhí)行

在這里插入圖片描述

duideduide沒有role所以沒發(fā)到工資

總結(jié)

本文簡單記錄了下簡單的springbatch的使用,包括item相關(guān),process編寫,step構(gòu)建和最終的job使用。springbatch還有一點(diǎn)是可以設(shè)置出現(xiàn)異常的處理策略,比如容忍數(shù)次異常,調(diào)過某些異常等,在真實(shí)使用中比較靈活,有機(jī)會再補(bǔ)充。

好了,以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:

相關(guān)文章

  • IDEA最新激活碼2021(IDEA2020.3.2最新永久激活方法)

    IDEA最新激活碼2021(IDEA2020.3.2最新永久激活方法)

    這篇文章主要介紹了IDEA最新激活碼2021(IDEA2020.3.2最新永久激活方法),本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java繼承超詳細(xì)教程

    Java繼承超詳細(xì)教程

    繼承是面向?qū)ο笳Z法的三大特征之一,繼承可以降低代碼編寫的冗余度,提高編程的效率,通過繼承,子類獲得了父類的成員變量和方法,一個(gè)子類如何繼承父類的字段和方法,如何修改從父類繼承過來的子類的方法呢,今天我們開始學(xué)習(xí)有關(guān)Java繼承的知識,感興趣的朋友一起看看吧
    2023-11-11
  • Mybatis批量插入和批量更新失敗問題

    Mybatis批量插入和批量更新失敗問題

    這篇文章主要介紹了Mybatis批量插入和批量更新失敗問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • IDEA解析Maven依賴過慢的問題

    IDEA解析Maven依賴過慢的問題

    文章介紹了如何優(yōu)化Maven構(gòu)建過程,包括更改Maven配置文件使用阿里源、調(diào)整JVM內(nèi)存參數(shù)以提升構(gòu)建性能,并提供了解決內(nèi)存不足問題的方法
    2026-02-02
  • pom文件中${project.basedir}的使用

    pom文件中${project.basedir}的使用

    這篇文章主要介紹了pom文件中${project.basedir}的使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 詳細(xì)講解Java抽象類示例

    詳細(xì)講解Java抽象類示例

    這篇文章主要介紹了 Java抽象類示例,抽象類通常用于定義一些公共的方法和屬性,但是這些方法沒有具體的實(shí)現(xiàn),需要的朋友可以參考下
    2023-05-05
  • Mybatis下動態(tài)sql中##和$$的區(qū)別講解

    Mybatis下動態(tài)sql中##和$$的區(qū)別講解

    今天小編就為大家分享一篇關(guān)于Mybatis下動態(tài)sql中##和$$的區(qū)別講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • SrpingDruid數(shù)據(jù)源加密數(shù)據(jù)庫密碼的示例代碼

    SrpingDruid數(shù)據(jù)源加密數(shù)據(jù)庫密碼的示例代碼

    本篇文章主要介紹了SrpingDruid數(shù)據(jù)源加密數(shù)據(jù)庫密碼的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Mybatis中的@Param及動態(tài)SQL詳解

    Mybatis中的@Param及動態(tài)SQL詳解

    這篇文章主要介紹了Mybatis中的@Param及動態(tài)SQL詳解,@Param是MyBatis所提供的作為Dao層的注解,作用是用于傳遞參數(shù),從而可以與SQL中的的字段名相對應(yīng),需要的朋友可以參考下
    2023-10-10
  • 詳解JavaEE 使用 Redis 數(shù)據(jù)庫進(jìn)行內(nèi)容緩存和高訪問負(fù)載

    詳解JavaEE 使用 Redis 數(shù)據(jù)庫進(jìn)行內(nèi)容緩存和高訪問負(fù)載

    本篇文章主要介紹了JavaEE 使用 Redis 數(shù)據(jù)庫進(jìn)行內(nèi)容緩存和高訪問負(fù)載,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08

最新評論

永安市| 扶余县| 巴塘县| 通州市| 东阳市| 濉溪县| 如东县| 木里| 攀枝花市| 南郑县| 西和县| 罗山县| 淅川县| 哈巴河县| 隆林| 临湘市| 西丰县| 澄江县| 额济纳旗| 富民县| 阿拉善左旗| 项城市| 辽阳市| 广宁县| 罗平县| 墨脱县| 大同县| 霍山县| 鸡西市| 海宁市| 慈溪市| 含山县| 西丰县| 孟村| 句容市| 张北县| 苍梧县| 湖北省| 巴马| 乐清市| 鹿邑县|