【问题标题】:How efficient are Hibernate's interceptors compared to database triggers?与数据库触发器相比,Hibernate 的拦截器效率如何?
【发布时间】:2016-02-05 17:12:42
【问题描述】:

由于I can't make MySQL to update a column with ON UPDATE,我正在考虑使用Hibernate's interceptors,在每次更新行时更新updated 表。

我唯一担心的是,与让 MySQL 更新它的理想情况相比,它意味着多少性能损失?

【问题讨论】:

  • 开启 mysql 的通用日志以捕获 Hibernate 发送到 MySQL 的内容。
  • 为了它的价值.. 更大的问题不是性能。相反,只有一种访问方法正在应用时间戳。因此,例如,如果您从数据库客户端或访问同一数据库的另一个客户端执行 UPDATE,则不会记录该更新时间戳。对于某些用例(例如合规性)来说,这可能是一个真正的问题
  • @SteveEbersole:真的没想到,谢谢。我想这种情况下我会同时使用这两种方法。

标签: mysql database performance hibernate triggers


【解决方案1】:

没有显着的性能损失,您也不需要拦截器。

我为此创建了一个example on GitHub

你需要创建一个 JPA 回调监听器:

public class UpdatableListener {

    @PrePersist
    @PreUpdate
    private void setCurrentTimestamp(Object entity) {
        if(entity instanceof Updatable) {
            Updatable updatable = (Updatable) entity;
            updatable.setTimestamp(new Date());
        }
    }

}

它使用这样定义的接口:

public interface Updatable {

    void setTimestamp(Date timestamp);

    Date getTimestamp();
}

然后您可以为所有实体定义一个基类:

@MappedSuperclass
@EntityListeners(UpdatableListener.class)
public class BaseEntity implements Updatable {

    @Column(name = "update_timestamp")
    private Date timestamp;

    @Override
    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }

    @Override
    public Date getTimestamp() {
        return timestamp;
    }
}

然后简单地让你的实体扩展它:

@Entity(name = "Post")
@Table(name = "post")
public class Post extends BaseEntity {
    ...  
}

@Entity(name = "PostComment")
@Table(name = "post_comment")
public static class PostComment extends BaseEntity {
    ...  
}

当您修改这些实体时:

doInJPA(entityManager -> {
    Post post = entityManager.find(Post.class, 1L);
    post.setTitle("Post");
    for(PostComment comment : post.getComments()) {
        comment.setReview("Review");
    }
});

Hibernate 将负责设置timestamp 列:

UPDATE  post
SET     update_timestamp = '2016-02-06 17:03:26.759' ,
        title = 'Post'
WHERE   id = 1
UPDATE  post_comment
SET     update_timestamp = '2016-02-06 17:03:26.76' ,
        post_id = 1 ,
        review = 'Review'
WHERE   id = 1
UPDATE  post_comment
SET     update_timestamp = '2016-02-06 17:03:26.76' ,
        post_id = 1 ,
        review = 'Review'
WHERE   id = 2

【讨论】:

猜你喜欢
  • 2023-03-31
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
相关资源
最近更新 更多