通过小项目学习23种设计模式(二)

通过读取文件导入数据库功能学习23种设计模式

  • 需求
  • 再次开始工作
  • 测试
  • 总结

需求

领导: 这垃圾代码竟然跑的起来,文件名是我随便给的,实际文件名是表名+下划线+时间的,时间就是当天时间,每天都会提供当天的文件,
实际文件名应该是MYFILE_20200630.dat
实际信号文件名应该是MYFILE_20200630.ctl
而且功能实际用的时候也不可能只是一个文件,可能有三四个文件,而且上线以后,根据业务需要,一定还会在新加文件,赶紧改改;

再次开始工作

理清需求,文件实际是表名+时间;
测试的时候会使用不同的时间;
实际会有多个文件;
以后还会添加文件;

通过微小的修改实现需求,提取公共参数即可
修改 BatTaskRun.java

package com.xiaoma.fileimport.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author mawuhui
 * @create 2020-06-30 17:59
 */
@Component
public class BatTaskRun {

    @Autowired
    FileReader reader;

    @Autowired
    FileToDataBase fileToDataBase;

    public int execute(String taskNo) {
        // 未传入时间的时候使用当前时间  如 20200630
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String taskDate = LocalDate.now().format(df);
        return execute(taskNo, taskDate);
    }

    public int execute(String taskNo, String taskDate) {
        // 文件名获取
        String fileName = taskNo +"_"+ taskDate;
        // 1. 信号文件读取
        List<String> ctlFile = reader.readTxtFile("E:\\project\\" + fileName + ".ctl");
        // 2. 数据文件读取
        List<String> datFile = reader.readTxtFile("E:\\project\\"+ fileName + ".dat");
        // 3. 校验行数
        /** 信号文件中的行数 */
        Integer ctllines = Integer.parseInt(ctlFile.get(3).split("=")[1]);
        /** 数据文件中的行数 */
        Integer datlines = datFile.size();
        if (!ctllines.equals(datlines)) {
            throw new RuntimeException("文件校验出错,文件实际条数:" + datlines + "信号文件条数:" + ctllines);
        }
        // 4. 执行入库
        fileToDataBase.execute(ctlFile, datFile);
        return 0;
    }
}

这里把表名写死了,也需要修改 FileToDataBase.java

package com.xiaoma.fileimport.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件数据解析导入数据库
 *
 * @author mawuhui
 * @since 2020-06-30 18:21
 */
@Component
public class FileToDataBase {
    @Autowired
    JdbcTemplate jdbcTemplate;

    /**
     * @param ctlFile
     * @param datFile
     * @return
     */
    public int execute(List<String> ctlFile, List<String> datFile) {
        String[] sql = buildSql(ctlFile, datFile);
        jdbcTemplate.batchUpdate(sql);
        return 0;
    }

    /**
     * @param ctlFile
     * @param datFile
     * @return
     */
    public String[] buildSql(List<String> ctlFile, List<String> datFile) {
        String[] s = new String[datFile.size()];
        // 这里tableName 写死了,需要修改
        String tableName = ctlFile.get(2).split("=")[1];
        StringBuilder builder1 = new StringBuilder();
        builder1.append("insert into ").append(tableName).append("(");

        String columns = ctlFile.get(0).split("=")[1].replace("%@#%", "").replace("][", ",");
        builder1.append(columns.substring(1, columns.length() - 1));
        builder1.append(") values(");

        int i = 0;
        for (String line : datFile) {
            List<String> temp = Arrays.asList(line.split("%@#%"));
            String dat = temp.stream().map(item -> "'" + item + "'").collect(Collectors.joining(","));
            s[i] = builder1.toString() + dat + ")";
            i++;
        }
        return s;
    }
}

FileReader.java 无修改

主启动类修改 FileImportApplication.java

package com.xiaoma.fileimport;

import com.xiaoma.fileimport.service.BatTaskRun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FileImportApplication implements CommandLineRunner {
    @Autowired
    BatTaskRun batTaskRun;

    public static void main(String[] args) {
    	//参数写一个就是使用当前日期,当提供测试文件日期不为当前日期的时候,传入日期为参数即可
		//SpringApplication.run(FileImportApplication.class, new String[]{"myfile"});
        SpringApplication.run(FileImportApplication.class, new String[]{"myfile", "20200630"});
    }

    /**
     * 文件导入数据库执行入口
     * 通过配置根据传入的文件导入编号找到对应的文件名
     *
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        String taskNo = args[0];
        if (args.length == 2) {
            String taskDate = args[1];
            batTaskRun.execute(taskNo, taskDate);
        } else {
            batTaskRun.execute(taskNo);
        }
    }
}

测试

将a.dat 和 a.ctl 文件名修改为 myfile_20200630.dat 和 myfile_20200630.ctl
执行FileImportApplication.java 中的main 方法后;
连接数据库,可以看到数据成功插入
通过小项目学习23种设计模式(二)_第1张图片

总结

看似需求很多,变化很大,其实也就是把参数提取出来就行了,不需要进行过多的改变;
只要文件格式不变,我的代码就没有问题;

你可能感兴趣的:(通过小项目学习设计模式)