【问题标题】: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 数据库中以事务安全方式(可以同时插入实体)来完成?

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

【问题讨论】:

    标签: mysql hibernate jpa transactions sequence


    【解决方案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();
        }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      • 2015-02-23
      • 2016-06-16
      相关资源
      最近更新 更多