使用Spring Data JPA简化JPA

Java中的数据库访问经历了一些步骤:

  • 首先,纯JDBC
  • 专有框架
  • EJB实体和JDO等标准
  • 开源框架,例如HibernateEclipseLink (当时称为TopLink)

JPA最终发布时,我的愿望似乎实现了。 最后,有一个标准来自Java来访问数据库

不幸的是,与Hibernate相比,JPA没有兑现承诺:例如,您没有Query by Example 。 更糟糕的是,在第一个版本中,JPA没有提供诸如Criteria之类的简单功能,因此即使简单的查询也必须通过JPQL实现,并因此通过String级联来实现。 恕我直言,这完全打败了ORM的目的。

JPA2抢救

最后,JPA2提供了在实际应用程序中可用的功能。 但是,我觉得仍然有很多样板代码可以编写一个简单的CRUD DAO

publicclassJpaDao{

    @PersistenceContext
    privateEntityManagerem;

    privateClassmanagedClass;

    privateJpaDao(ClassmanagedClass){
        this.managedClass=managedClass;
    }

    publicvoidpersist(Eentity){
        em.persist(entity);
    }

    publicvoidremove(Eentity){
        em.remove(entity);
    }

    publicEfindById(PKid){
        returnem.find(managedClass,id);
    }
}

有些人会(并且确实)反对在这种用例中不需要DAO:只需将EntityManager注入服务类中并直接使用即可。 这可能是一个相关的观点,但是只有在没有查询的情况下,才需要在数据访问和业务逻辑之间进行区分。

JPA2中的样板代码

两个简单的用例突出了JPA 2: @NamedQuery和简单条件查询中无用的样板代码。 在第一种情况下,您必须通过实体管理器获取命名查询的句柄,然后像下面这样设置潜在参数:

Queryquery=em.createNamedQuery("Employee.findHighestPaidEmployee");

在第二个中,您必须使用CriteriaBuilder实现自己的查询:

CriteriaBuilderbuilder=em.getCriteriaBuilder();
CriteriaQueryquery=builder.createQuery(Person.class);
RootfromPerson=query.from(Person.class);
returnem.createQuery(query.select(fromPerson)).getResultList();

恕我直言,这些代码行什么都没有带到桌上,只是使我们自己的代码混乱。 一次偶然的机会,我发现了Hades项目,该产品基于此结论并为您编写了简单的代码。

Spring Data JPA

鉴于一些出色的OpenSource项目的命运,Hades的表现要好得多,因为Hades已经以Spring Data JPA的名称引入了Spring生态系统。 SDJ开箱即用,提供具有高级CRUD功能的DAO。 例如,以下接口可以按原样使用:

publicinterfaceEmployeeRepositoryextendsJPARepository

给定一些Spring魔术,将在运行时提供以下方法的实现:

  • void deleteAllInBatch()
  • void deleteInBatch(Iterable<Employee> entities)
  • List<Employee> findAll()
  • List<Employee> findAll(Sort sort)
  • void flush()
  • <S extends Employee> List<S> save(Iterable<S> entities)
  • Employee saveAndFlush(Employee entity)
  • Page<Employee> findAll(Pageable pageable)
  • Iterable<Employee> findAll(Sort sort)
  • long count()
  • void delete(ID id)
  • void delete(Iterable<? extends Employee> entities)
  • void delete(Employee entity)
  • void deleteAll()
  • boolean exists(Long id)
  • Iterable<Employee> findAll()
  • Iterable<Employee> findAll(Iterable ids)
  • Employee findOne(Long id)
  • <S extends Employee> Iterable<S> save(Iterable<S> entities)
  • <S extends Employee> S save(S entity)

是的,SDJ为您提供了一个通用的DAO,就像周围的许多框架一样,但是在这里,与底层实现的连接由该框架免费处理。 对于那些不需要全部并且更喜欢严格的最低要求的人,您还可以使用以下策略,在其中您必须从上面的列表中选择方法(并使用注释):

@RepositoryDefinition(domainClass=Employee.class,idClass=Long.class)
publicinterfaceEmployeeRepository{
    longcount();
    Employeesave(Employeeemployee);
}

确实不错,但是最好的还没到。 还记得我们不得不自己编写的上述两个用例吗? 第一种方法很简单,只需将不合格的查询名称添加到接口即可,如下所示:

@RepositoryDefinition(domainClass=Employee.class,idClass=Long.class)
publicinterfaceEmployeeRepository{
    ...
    EmployeefindHighestPaidEmployee();
}

JPA存储库中提供了第二个用例,查找所有员工。 但是,让我们假装一秒钟,我们有一个WHERE子句,例如名字。 SDJ能够根据方法名称处理简单查询:

@RepositoryDefinition(domainClass=Employee.class,idClass=Long.class)
publicinterfaceEmployeeRepository{
    ...
    ListfindByLastname(StringfirstName);
}

我们只需要编写一个接口及其方法的代码:不涉及实现代码或元模型的生成! 不用担心,如果您需要实现一些复杂的查询,则SDJ允许您连接自己的实现。

结论

如果您已经是Spring用户,那么Spring Data JPA确实是(真的!)必须。 如果不是,那么欢迎您对其进行测试,以亲自查看其附加值。 恕我直言,SDJ是JavaEE尚未杀死Spring的原因之一:它桥接了注入部分,但样板代码仍然无处不在。

本文不是一个方法,而是一个让您进入SDJ的预告片。 您可以在此处以Maven / Eclipse格式找到本文的资源。

对于尚未加入JPA的用户,可以使用Data JDBC ; 对于那些远远超出此范围的用户(认为大数据); 有一个数据Hadoop 。 检查所有Spring Data项目

翻译自: https://blog.frankel.ch/easier-jpa-with-spring-data-jpa/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值