You need to enable JavaScript to run this app. Java中如何实现按目标zip文件存在状态精准清理对应数据库表
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何实现按目标zip文件存在状态精准清理对应数据库表

代码优化方案

核心调整逻辑

当前代码的核心问题是全表删除操作早于文件扫描环节执行,没有基于目录下实际存在的文件类型判断清理范围,同时存在单例Bean的成员变量并发安全隐患。调整时保持原有业务流程不变,仅做以下小范围改动:

  • 流程顺序反转:先对目标目录做一次预扫描,标记是否存在对应命名标识的zip文件
  • 删除逻辑条件化:仅当对应类型文件存在时,才执行目标表的全量删除,无对应文件的表不做任何操作
  • 修正并发隐患:将原成员变量isEquity改为方法内局部变量,避免单例Bean被多线程调用时出现数据写表错位

调整后完整代码

@Service
public class IImporter {

    private final static Logger log = LoggerFactory.getLogger(IImporter.class);
    private final static String EQU_FILE_TAG = "EQUFULLFILE";
    private final static String NONEQU_FILE_TAG = "NONEQUFULLFILE";

    @Autowired
    private IFullreader IFullreader;

    @Autowired
    private ZipWalker zipWalker;

    @Autowired
    private SessionFactory sessionFactory;

    @Transactional
    public void importDir(Path indir) throws IOException {
        // 预扫描目录,标记两类文件是否存在
        boolean hasEquFile = false;
        boolean hasNonEquFile = false;
        
        // 用try-with-resources确保Stream资源关闭
        try (Stream<Path> pathStream = Files.walk(indir, 1, FOLLOW_LINKS)) {
            List<Path> zipFiles = pathStream
                .filter(Files::isRegularFile)
                .filter(f -> f.getFileName().toString().endsWith(".zip"))
                .sorted()
                .toList();
            
            for (Path zipFile : zipFiles) {
                String fileName = zipFile.getFileName().toString();
                if (fileName.contains(EQU_FILE_TAG)) {
                    hasEquFile = true;
                }
                if (fileName.contains(NONEQU_FILE_TAG)) {
                    hasNonEquFile = true;
                }
            }

            // 按标记执行对应表的清理,无对应文件则跳过
            if (hasEquFile) {
                log.info("检测到权益类全量文件,执行EquData表全量清理");
                sessionFactory.getCurrentSession().createQuery("delete from EquData").executeUpdate();
            } else {
                log.info("未检测到带EQUFULLFILE标识的文件,跳过EquData表清理");
            }

            if (hasNonEquFile) {
                log.info("检测到非权益类全量文件,执行NonEquData表全量清理");
                sessionFactory.getCurrentSession().createQuery("delete from NonEquData").executeUpdate();
            } else {
                log.info("未检测到带NONEQUFULLFILE标识的文件,跳过NonEquData表清理");
            }

            log.info("开始处理目录: {}", indir.toString());
            // 复用预扫描得到的zip文件列表做后续处理,避免重复遍历目录
            zipFiles.forEach(f -> zipWalker.processZipFile(f, this::importFile));
        }
    }

    private void importFile(Path path) {
        // 改为局部变量,避免单例Bean的并发安全问题
        boolean isEquity = path.getFileName().toString().contains(EQU_FILE_TAG);
        if (isEquity) {
            // 原有权益类文件读取、数据写入逻辑保持不变
        } else {
            // 原有非权益类文件读取、数据写入逻辑保持不变
        }
    }
}

关键改动说明

  • 预扫描阶段一次性把目录下所有合规zip文件读取成列表,既可以判断文件存在性,又能避免原流程中重复遍历两次目录的性能浪费
  • 全表删除操作完全和文件存在性绑定,不存在对应类型文件时绝对不执行删除,避免无意义的全表数据清空
  • 修正了原代码里Files.walk返回的Stream未关闭的资源泄漏问题,同时把路径后缀判断从全路径字符串匹配改为文件名匹配,避免路径目录名带.zip后缀导致的误判
  • 移除了作为成员变量的isEquity,避免Spring单例Bean在多线程并发调用时,不同请求的判断值互相覆盖,导致数据写错表的潜在问题

内容的提问来源于stack exchange,提问作者Symonds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.13 05:24:07