对于新项目,JPA始终是推荐的用于处理关系数据的工具吗?或者在某些情况下,Spring JdbcTemplate是更好的选择?您的回应中应考虑以下因素:
- 新数据库架构与现有架构和表
- 开发人员专业知识水平
- 易于与数据缓存层集成
- 性能
- 还有其他需要考虑的因素吗?
Answers:
如果您不想通过域模型访问数据库架构,请使用Spring JdbcTemplate。使用JdbcTemplate,您将使用较低级别的访问权限,具有更大的灵活性,但可能还会有更多样板。
Spring JdbcTemplate可以更轻松地与外部数据库模式和存储过程焦点一起使用。使用JPA,您需要确保数据库架构正确映射到域模型。
两种技术都需要开发人员了解关系数据库,SQL和事务。使用JPA,您会获得更多隐藏的复杂性。
据我所知,JPA更容易插入数据缓存层,因为面向对象的焦点使缓存条目的标识,更新和失效变得更加容易。
您可以更好地微调基于JdbcTemplate的后端,但是在大多数情况下,涉及更多的代码。
需要考虑的其他方面是,尽管使用JPA,您可以获得数据库模式的域模型,但通常仍需要使用其他DTO类。使用JdbcTemplate,您可以直接使用DTO类。
我对这篇文章有些迟了,但是我倾向于在ORM上使用JdbcTemplate。我知道SQL(非常好),并且真的不想被我的数据库“抽象化”。我发现大多数时候,我的应用程序都在使用数据库视图,在这些视图中,我可以将大多数业务逻辑推到最高点。我已经正确分层了具有JdbcTemplate实现的DAO。感觉“干净”,大多数样板代码都被JdbcTemplate隐藏了(它的在线文档似乎比ORM东西要好得多)。我在有限的时间内使用过Hibernate之类的工具,发现它可以正常工作,为我节省了一些时间...但是,当它无法正常工作时,我花了几天的时间进行“ WTF”调试。我从来不需要花费超过20分钟的时间调试JdbcTemplate DAO impls。正如其他人指出的那样,我认为关键是您对SQL / Schema Design的适应程度如何
我同意@Timo。我将添加/扩展的唯一其他见解是,ORM具有与从纯SQL访问数据不同的语义。
ORM的重点是尽可能抽象出您的数据完全在数据库中的事实。正确使用ORM时,所有持久性操作都将在一个(希望的)薄层中进行。您的模型对象几乎没有持久性代码;您正在使用ORM的事实对于您的模型应该是不可见的。
因此,ORM非常擅长使您轻松进行某些类型的操作,即简单的CRUD操作。您可以轻松加载模型对象,显示它们,更新它们,删除它们。这使您的工作变得更轻松,因为当您访问数据时,您会得到模型对象,可以在上面写业务逻辑。如果使用JDBC,则必须从数据中“合并”对象实例,这可能很复杂且容易出错。
ORM并非始终是最佳选择。JPA是用于工作的工具,如果该工具不足以完成工作,那么您将希望找到更好的工具。例如,我有一个场景,我必须复制整个对象图并保存这些对象的新副本。如果我使用过ORM(就像我尝试做的那样),则必须将所有对象从数据库中加载出来,然后复制它们,然后保存新对象。我花了太长时间。
更好的解决方案是简单地使用基于jdbc的操作和“通过选择插入” sql调用来创建新行。速度很快,代码更简单。
要考虑的另一件事是,您对JDBC感到满意,并且有最后期限,因此不必急于使用ORM。Spring JdbcTemplate类非常强大且有用。有时,最好的工具就是您所知道的工具。您应该熟悉ORM,但不一定对期望很高的项目有所了解。有很多东西要学习,但它并不简单-实际上,您在选择使用jdbc vs orm时要权衡一组复杂性。
其他答案中未提及,但可以同时使用。在我的应用程序中,我使用JPA和JdbcTemplate,对于粗体类型操作,我使用JPA,但是对于报告或更容易使用jdbcTemplate的地方。
@Repository
public class FooRepository
{
@PersistenceContext
private EntityManager entityManager;
@Autowired(required = true)
private JdbcTemplate jdbcTemplate;
public void saveFoo(Foo foo)
{
this.entityManager.persist(foo);
}
public List<SomeReportPojo> getSomeReport()
{
return this.jdbcTemplate.queryForList("SELECT .. ",SomeProjectPojo.class);
}
}
关于Spring的伟大之处在于,从JPA异常到Spring Dao异常层次结构的异常转换可与JPA和jdbcTemplate一起使用。因此,在合理时使用JPA,在合理时使用jdbcTemplate。
getSomeReport()
是this.jdbcTemplate. ...
不是this.entityManager. ...
?