一、说明

本系列主题在工作场景下,使用 AI 提供的帮助。运用好 AI 的功能,可以使得工作事半功倍。

今天的工作场景:需要的小功能:每日递增生成4位流水号。此功能主要考虑以下3点。

①. 按日递增

②. 持久化

③. 线程安全

我们不需要自己编码:只要给 AI提示词,使用的是豆包-AI助手。

我们以后把 AI生成的代码统一放在yiyi.coding.ai总包下。

二、实操

给AI 的消息是:Java 实现每日递增生成4位流水号方案。不引入依赖

AI 生成的代码(没有package)如下:

package yiyi.coding.ai;

import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 每日递增4位流水号生成器(原生文件持久化版,无任何第三方依赖)
 * 持久化文件格式:properties(key=date, serial),避免JSON依赖
 */
public class PersistentDailySerialGenerator {
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
    // 持久化文件路径(可自定义,如:/data/serial/serial.properties)
    private static final File SERIAL_FILE = new File("serial_number.properties");
    // 原子类存储日期和序号
    private final AtomicReference<String> currentDate = new AtomicReference<>();
    private final AtomicInteger currentSerial = new AtomicInteger(1);

    // 构造方法:启动时加载文件中的序号(原生IO)
    public PersistentDailySerialGenerator() {
        loadFromFile();
    }

    /**
     * 生成流水号(带日期,如202511270001)
     */
    public String generateSerialNumber() {
        return generateSerialNumber(true);
    }

    /**
     * 重载:可选是否拼接日期
     */
    public String generateSerialNumber(boolean withDate) {
        String today = LocalDate.now().format(DATE_FORMATTER);

        // 跨天重置
        if (!today.equals(currentDate.get())) {
            synchronized (this) {
                if (!today.equals(currentDate.get())) {
                    currentDate.set(today);
                    currentSerial.set(1);
                    saveToFile(); // 重置后持久化
                }
            }
        }

        // 递增并处理上限
        int serial = currentSerial.getAndIncrement();
        if (serial > 9999) {
            throw new RuntimeException("当日4位流水号已达上限(9999)");
        }

        // 持久化最新状态
        saveToFile();

        // 格式化返回
        String serialStr = String.format("%04d", serial);
        return withDate ? today + serialStr : serialStr;
    }

    /**
     * 原生IO加载持久化文件(Properties格式,无依赖)
     */
    private void loadFromFile() {
        // 文件不存在则初始化
        if (!SERIAL_FILE.exists()) {
            // 创建父目录(避免文件路径不存在)
            if (SERIAL_FILE.getParentFile() != null) {
                SERIAL_FILE.getParentFile().mkdirs();
            }
            currentDate.set(LocalDate.now().format(DATE_FORMATTER));
            currentSerial.set(1);
            saveToFile(); // 初始化文件
            return;
        }

        // 原生IO读取Properties文件
        Properties props = new Properties();
        try (FileReader reader = new FileReader(SERIAL_FILE)) {
            props.load(reader);
            // 读取日期和序号(兼容文件损坏场景)
            String savedDate = props.getProperty("date", LocalDate.now().format(DATE_FORMATTER));
            int savedSerial = Integer.parseInt(props.getProperty("serial", "1"));

            currentDate.set(savedDate);
            currentSerial.set(savedSerial);
        } catch (IOException | NumberFormatException e) {
            // 文件损坏时初始化
            currentDate.set(LocalDate.now().format(DATE_FORMATTER));
            currentSerial.set(1);
            saveToFile();
            System.err.println("加载流水号文件失败,已初始化新状态:" + e.getMessage());
        }
    }

    /**
     * 原生IO保存状态到文件(Properties格式)
     */
    private void saveToFile() {
        // 加锁保证写文件原子性
        synchronized (this) {
            Properties props = new Properties();
            props.setProperty("date", currentDate.get());
            props.setProperty("serial", String.valueOf(currentSerial.get()));

            // 原生IO写入文件(BufferedWriter提升性能)
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(SERIAL_FILE))) {
                props.store(writer, "Daily Serial Number Persistence");
            } catch (IOException e) {
                throw new RuntimeException("保存流水号到文件失败", e);
            }
        }
    }

    // 测试:验证持久化(重启后序号延续)
    public static void main(String[] args) {
        PersistentDailySerialGenerator generator = new PersistentDailySerialGenerator();
        // 生成5个序号,验证文件持久化
        for (int i = 0; i < 5; i++) {
            System.out.println("生成序号:" + generator.generateSerialNumber());
        }
        // 查看serial_number.properties文件,内容如下:
        // #Daily Serial Number Persistence
        // #Thu Nov 27 10:00:00 CST 2025
        // date=20251127
        // serial=6
    }
}

main 方法运行后,生成数据:

D:\Java\jdk-25.0.1\bin\java.exe ...
生成序号:202511270001
生成序号:202511270002
生成序号:202511270003
生成序号:202511270004
生成序号:202511270005

进程已结束,退出代码为 0
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐