在一天内为实体生成唯一的序列号

Posted

技术标签:

【中文标题】在一天内为实体生成唯一的序列号【英文标题】:Generate unique sequence number for entity during one day 【发布时间】:2011-11-06 20:17:24 【问题描述】:

我需要为插入到表中的实体生成唯一编号。每个编号由实体创建日期和序列号组成:日期 + sn。序列号必须在第二天开始时重置。

| id | creation date | unique number |
--------------------------------------
| 1  | Sep 1, 2010   | 201009011     |
| 2  | Sep 1, 2010   | 201009012     |
| 3  | Sep 2, 2010   | 201009021     |
| 4  | Sep 2, 2010   | 201009022     |

如何使用 JPA over Hibernate(目前它们用于所有数据库交互)和在 mysql 数据库中以事务安全方式(可以同时插入实体)来完成?

当然,我会欣赏所有其他方法的描述。谢谢。

【问题讨论】:

【参考方案1】:

您可以在插入之前使用触发器。

DELIMITER $$

CREATE TRIGGER bi_table1_each BEFORE INSERT ON table1 FOR EACH ROW
BEGIN
  DECLARE creationdate DATE;
  DECLARE newdayid INTEGER;

  SET creationdate = new.`creation date`;
  SELECT count(*) + 1 INTO newdayid FROM table1 
    WHERE table1.`creation date` = creationdate;

  -- NEW.`unique number` = CONCAT(DATE_FORMAT(creationdate,'%Y%m%d'),newdayid);
  NEW.`unique number` = CONCAT(DATE_FORMAT(creationdate,'%Y%m%d')
                               RIGHT(CONCAT('00000000',newdayid),8));

END $$

DELIMITER ;

请注意,将 newdayid 中的小数位数固定为 8 位(或其他)可能是个好主意,如果您不希望这样,只需使用注释掉的行。

【讨论】:

是否保证没有其他人可以开始另一个实体插入?否则可能出现竞争条件,并且可以创建具有相同编号的实体。【参考方案2】:

您可以结合使用数据库生成的值,例如 @Johan 建议和使用 @Generated(GenerationTime.INSERT) Hibernate Annotation Extensions。

2.4.3.5. Generated properties

某些属性是在插入或更新时由您的 数据库。 Hibernate 可以处理这些属性并触发一个 随后选择读取这些属性

creationDate字段可以在JPA支持的@PrePersit回调事件中设置

@PrePersit

在实体管理器持久化操作实际之前执行 执行或级联。此调用与持久化同步 操作。

示例(Getter 和 setter 省略以便更清楚)

@Entity
public class Entity

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    @Generated(GenerationTime.INSERT) @Column(insertable = false)
    private String uniqueNumber;

    @Temporal(TemporalType.TIMESTAMP)
    private Date creationDate

    @PrePersist
    public void prePersit()
    
        creationDate = new Date();
    

【讨论】:

以上是关于在一天内为实体生成唯一的序列号的主要内容,如果未能解决你的问题,请参考以下文章

如何在一天内的特定时间段内应用累积python函数,然后从第二天开始重置

如何使用 Quartz 安排作业在一天内多次但固定的时间运行

如何在一年多的时间内找到一天内订单超过 1 个的客户

为每个员工选择一天中最早时间戳的完整记录[重复]

如何有效地计算熊猫时间序列中的滚动唯一计数?

IDEA 实体类生成serialVersionUID