Spring 的重点是尽可能不干扰您的代码,您应该在代码中尽可能少地看到 Spring。基本上,这就是 Spring 的重点和目标。
当你通常在没有 spring 的情况下使用 hibernate 时,你会有某种构造 hibernate SessionFactory 的单例。
public class HibernateUtil {
private static SessionFactory sf;
static {
sf = ew Configuration().configure().buildSessionFactory();
}
public static getSessionFactory() {
return sf;
}
}
接下来您会看到代码中充满了对HibernateUtils.getSesionFactory() 的调用。您需要手动创建 Session 并启动/提交事务。
public void save(Entity e) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
try {
session.save(e);
tx.commit();
} catch (HIbernateException he) {
tx.rollback();
} finally {
session.close();
}
}
但是,由于两个原因,这段代码很糟糕。首先,您手动管理事务,一段时间后变得很痛苦,您想使用声明性事务管理。第二个你在错误的层管理事务,事务应该在服务层管理。现在要实现这一点,您必须在服务层中获取SessionFactory,这会突然将数据访问层变成一个泄漏的抽象。
Spring 可以在这两件事上为您提供帮助,它可以进行声明式 tx 管理并隐藏您正在使用 Hibernate 的事实,而不是使其成为泄漏的抽象。
@Inject
private SessionFactory sf;
public void save(Entity e) {
sf.getCurrentSession().save(e);
}
这在 Spring 方式中是相同的。事务将在服务级别启动(带有@Transactional 或@TransactionAttributes 注释)。
对于 JPA,这或多或少是相同的,但是由于 JPA 是标准 Spring 尝试尽可能地遵循这些。所以 Spring 中的普通 JPA 代码和 JPA 代码没有太大区别(除非您在独立应用程序中使用 JPA 而不是 JEE 容器,否则 JPA 代码就像休眠代码一样)。