首页 > 解决方案 > 使用 Hibernate seesion.delete() 的更好方法是按 ID 删除还是按对象删除?

问题描述

我正在开发一个使用 Spring MVC 构建的应用程序,它使用 Hibernate 与数据存储进行交互。当我尝试实现删除功能时,我发现有多种方法可以实现 session.delete()。总之,我很困惑以下两种方法中的哪一种是实现 Hibernate seesion.delete() 的更好方法(更具体地说,标准方法)。

由于这个 API 调用将在未来阶段变成微服务,我想这是从 web 获取 userId 而不是整个对象的标准方法。

方法一:

@Transactional    
public void deleteUser(User user) {
    sessionFactory.getCurrentSession().delete(user);
}

方法二:

@Transactional
public void deleteUser(int userId) {
    Query q = session.createQuery("delete User where id = :userId");
    query.setParameter("userId", userId);
    q.executeUpdate();
}

方法三:

@Transactional
public void deleteOrg(int userId) {
    User user = sessionFactory.getCurrentSession().get(User.class, userId);
    sessionFactory.getCurrentSession().delete(user);
}

标签: springhibernatespring-mvcspring-boothibernate-session

解决方案


Gauillaume F.的答案的更多细节。我建议使用方法 4(高效、可公开的服务和 Hibernate 的惯用用法)。

方法一

@Transactional    
public void deleteUser(User user) {
    sessionFactory.getCurrentSession().delete(user);
}
  • 删除与会话缓存同步
  • user必须是 Hibernate 控制下的实例。所以它不能直接暴露为服务。
  • 足够高效。这取决于首先如何检索实例。

方法二

@Transactional
public void deleteUser(int userId) {
    Query q = session.createQuery("delete User where id = :userId");
    query.setParameter("userId", userId);
    q.executeUpdate();
}
  • 高效(没有实例从数据库加载或放入会话缓存)
  • 可以直接暴露为服务
  • 未与会话缓存同步
  • 不必要地使用 HQL

方法三

@Transactional
public void deleteOrg(int userId) {
    User user = sessionFactory.getCurrentSession().get(User.class, userId);
    sessionFactory.getCurrentSession().delete(user);
}
  • 足够高效(实例首先从数据库加载,放入会话缓存然后删除)
  • 可以直接暴露为服务
  • 与会话缓存同步

方法四

@Transactional
public void deleteOrg(int userId) {
    User user = sessionFactory.getCurrentSession().load(User.class, userId);
    sessionFactory.getCurrentSession().delete(user);
}
  • 高效(不加载数据;而是将代理放入会话缓存中)
  • 可以直接暴露为服务
  • 与会话缓存同步

推荐阅读