我正在构建一个新的Web应用程序,并且正在使用Spring,JPA / Hibernate和Postgres。我的某些表具有creation_ts和lastupdate_ts列,它们是时间戳列,用于跟踪何时发生插入以及何时在行中进行最后更新。
我还在表中的列使用命名约定,因此,根据设计策略,每个表都保证有两列pkey(这是整数代理键)和用于乐观锁定的版本。
我有两种方法可以使这些字段保持最新状态。
选项A:使用触发器
这是我现在所拥有的解决方案,我有两个Postgres触发器,它们会在插入和更新时触发,并将使这些字段保持最新状态。我有两节课。
@MappedSuperclass public abstract class PersistableObject { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="pkey") private Integer pkey; @Version @Column(name="version") private Integer version; public Integer getPkey() { return this.pkey; } public Integer getVersion() { return this.version; } }
我有
@MappedSuperclass public class TimeStampedPersistableObject extends PersistableObject { @Column(name = "creation_ts") @Temporal(TemporalType.DATE) @org.hibernate.annotations.Generated(value = GenerationTime.INSERT) private Date creationTimestamp; @Column(name = "update_ts") @Temporal(TemporalType.DATE) @org.hibernate.annotations.Generated(value = GenerationTime.ALWAYS) private Date updateTimestamp; public Date getCreationTimestamp() { return this.creationTimestamp; } public Date getUpdateTimestamp() { return this.updateTimestamp; } }
选项B:使用JPA侦听器
在此选项中,我将使用JPA侦听器将列的时间戳记保持最新。
我的问题:
这两种方法中哪一种更好?正如我所看到的,这是我个人对每种选择的利弊清单,我很高兴听到别人对这两种选择的经验。
选项A优点:
选项A的缺点:
选项B优点:
选项B缺点:
对于将完全控制数据库和Java代码的新应用程序,您将如何解决该问题。
在插入和更新后必须进行选择以读取触发器放置的值。
您可以使用INSERT ... RETURNING 或UPDATE ... RETURNING检索由触发器更改的值,因此无需执行其他SELECT。
INSERT ... RETURNING
UPDATE ... RETURNING
除此之外,我会说这取决于您的环境。如果应用程序是关键任务,并且如果这些列的维护不正确,将导致惨败,那么我会坚持使用触发器。
如果这只是为了前端的方便(并且可以优雅地处理由于不正确的值引起的冲突),那么JPA方法可能更易于维护。