java项目实现流水号自动增长

本文介绍了一种基于AtomicInteger自增实现的分组编号方案,该方案在项目启动时初始化最大分组编号,并通过线程安全的方式获取新的分组编号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中有一个规则编号字段,从1开始,编号长度为5位,那么第一条数据编号就是00001。

实现的基本思路就是项目启动时,从数据库获取当前最大值,作为静态变量存储;
业务获取新的编码,考虑并发问题,获取编码方法(编码自增部分)为synchronized同步方法,如果自增为原子操作,则无需同步;
编码前置0,使用String.format("%05d", newNum);格式化获取。

实现代码如下:

public class GroupServiceImpl implements IGroupService{

    @Autowired
    private IGroupDao groupDao;

    //静态变量存储最大值
    private static final AtomicInteger atomicNum = new AtomicInteger();
    //初始化分组编号
    private final int INIT_GROUP_NUM = 0;

    /**
     * @Author  javaloveiphone
     * @Description :初始化设置分组编号最大值
     * @throws Exception
     * void
     */
    @PostConstruct
    public void initMaxNum(){
        try{
            int maxGroupNum = groupDao.getMaxGroupNum();
            if(maxGroupNum<INIT_GROUP_NUM){
                maxGroupNum = INIT_GROUP_NUM;
            }
            if(logger.isDebugEnabled()){
                logger.debug("初始化分组编号最大值为:"+maxGroupNum);
            }
            atomicNum.set(maxGroupNum);
        }catch(Exception e){
            logger.error("初始化获取分组编号最大值异常",e);
        }
    }

    /**
     * @Author  javaloveiphone
     * @Description :获取最新分组编号
     * @return
     * int
     * 注:此方法并没有使用synchronized进行同步,因为共享的编号自增操作是原子操作,线程安全的
     */
    public String getNewAutoNum(){
        //线程安全的原子操作,所以此方法无需同步
        int newNum = atomicNum.incrementAndGet();
        //数字长度为5位,长度不够数字前面补0
        String newStrNum = String.format("%05d", newNum);
        return newStrNum;
    }
}
### Java实现自动递增顺序编号生产者的思路 在Java应用程序中,要创建一个能够生成自动递增序列号的功能模块,通常会考虑线程安全性和持久化存储等问题。下面提供了一种基于内存中的原子变量以及数据库自增长字段两种方式来构建这样的服务。 #### 方案一:使用 `AtomicLong` 类型作为计数器 对于单机版应用来说,可以利用JDK自带的 `java.util.concurrent.atomic.AtomicLong` 来维护一个全局唯一的序号。该类提供了高效的CAS(Compare And Swap)算法保证了多线程环境下数值更新的安全性。 ```java import java.util.concurrent.atomic.AtomicLong; public class SequenceGenerator { private final AtomicLong counter = new AtomicLong(); public long nextId() { return counter.incrementAndGet(); } } ``` 这种方法简单易行,在同一进程中能很好地工作,但如果涉及到分布式部署,则无法满足需求[^1]。 #### 方案二:通过关系型数据库表设计来自动生成ID 当面对更复杂的情况——例如需要跨多个服务器实例共享相同的序列时,可以通过定义一张专门用于记录最新已分配号码的数据表,并借助SQL语句完成插入操作的同时获取新产生的主键值(即新的唯一标识符)。大多数现代的关系型数据库管理系统都支持这种特性,像MySQL就有AUTO_INCREMENT属性可用于整数类型的列上。 假设有一个名为 `sequence_table` 的表格结构如下: | Column Name | Data Type | |-------------|-----------| | id | BIGINT | 那么可以在每次请求新的流水号之前先执行一次INSERT INTO ... ON DUPLICATE KEY UPDATE...命令,从而确保即使并发情况下也能得到连续不重复的结果集。 ```sql -- 初始化数据表 CREATE TABLE IF NOT EXISTS sequence_table ( id BIGINT AUTO_INCREMENT PRIMARY KEY ); -- 获取下一个id INSERT INTO sequence_table VALUES () ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id+1); SELECT LAST_INSERT_ID(); ``` 接着配合JDBC API编写相应的DAO层方法即可轻松集成到业务逻辑当中去。 以上就是关于如何用Java代码实现在本地或集群环境中产生有序且不会冲突的身份码的技术要点概述[^2]。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值