我应该使用Java 8默认方法手动实现的Spring数据仓库方法吗?

前端之家收集整理的这篇文章主要介绍了我应该使用Java 8默认方法手动实现的Spring数据仓库方法吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
当使用新的 Spring Data Evans发行版时,很高兴能够使用一些与 Java 8一起使用的一些好东西.其中一个是接口中的默认实现.下面的存储库使用QueryDSL来使查询类型安全.

我的问题是,在我写这篇文章之前,我使用了一个单独的UserRepositoryCustom接口的模式为findByLogin,然后另一个类UserRepositoryImpl,并在该类中,我将有@PersistenceContext获取当前的EntityManager.

当我没有课程时,如何获得EntityManager?甚至有可能吗

  1. @Repository
  2. public interface UserRepository extends JpaRepository<User,UUID> {
  3.  
  4. final QUser qUser = QUser.user;
  5.  
  6. // How do I get the entityManager since this is a interface,i cannot have any variables?
  7. //@PersistenceContext
  8. //EntityManager entityManager;
  9.  
  10. public default Optional<User> findByLogin(String login) {
  11. JPAQuery query = new JPAQuery(entityManager);
  12. User user = query
  13. .from(qUser)
  14. .where(
  15. qUser.deleter.isNull(),qUser.locked.isFalse(),qUser.login.equalsIgnoreCase(login)
  16. )
  17. .singleResult(qUser);
  18.  
  19. return Optional.ofNullable(user);
  20. }
  21. }

解决方法

只能使用默认方法来委派对其他存储库方法调用.默认方法(按定义)不能访问实例的任何状态(因为接口没有).他们只能委托其他接口方法调用其他类的静态方法.

实际上,使用reference documentation中描述的自定义实现是正确的方法.这是简短的版本供参考(以防其他人也想知道):

  1. /**
  2. * Interface for methods you want to implement manually.
  3. */
  4. interface UserRepositoryCustom {
  5. Optional<User> findByLogin(String login);
  6. }
  7.  
  8. /**
  9. * Implementation of exactly these methods.
  10. */
  11. class UserRepositoryImpl extends QueryDslRepositorySupport implements UserRepositoryCustom {
  12.  
  13. private static final QUser USER = QUser.user;
  14.  
  15. @Override
  16. public Optional<User> findByLogin(String login) {
  17.  
  18. return Optional.ofNullable(
  19. from(USER).
  20. where(
  21. USER.deleter.isNull(),USER.locked.isFalse(),USER.login.equalsIgnoreCase(login)).
  22. singleResult(USER));
  23. }
  24. }
  25.  
  26. /**
  27. * The main repository interface extending the custom one so that the manually
  28. * implemented methods get "pulled" into the API.
  29. */
  30. public interface UserRepository extends UserRepositoryCustom,CrudRepository<User,Long> { }

请注意,命名约定在这里很重要(但是如果需要,可以进行自定义).通过扩展QueryDslRepositorySupport,您可以访问from(…)方法,以便您不必自己与EntityManager进行交互.

或者,您可以让UserRepository实现QueryDslPredicateExecutor并从存储库外部传递谓词,但是让您最终可以使用需要使用Querydsl(可能是不需要的)的客户端,另外您还没有获取可选的包装器类型OOTB.

猜你在找的Java相关文章