我应该使用Java 8默认方法来手动实现Spring Data存储库方法吗? [英] Should I use Java 8 default methods for manually implemented Spring Data repository methods?

查看:175
本文介绍了我应该使用Java 8默认方法来手动实现Spring Data存储库方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用新的Spring Data Evans版本时,很高兴能够使用java 8附带的一些好东西。其中一个是接口中的默认实现。下面的存储库使用QueryDSL使查询类型安全。

When using the new Spring Data Evans release it's nice to be able to use some of the nice stuff that came with java 8. One of them is default implementations in interfaces. The repository below uses QueryDSL to make queries type safe.

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

My problem is that before when I wrote this I used the pattern of a separate UserRepositoryCustom interface for the findByLogin and then another class UserRepositoryImpl and in that class I would have the @PersistenceContext to get the current EntityManager.

如何做我没有课时,我得到 EntityManager ?是否可能?

How do I get the EntityManager when I don't have a class? Is it even possible?

@Repository
public interface UserRepository extends JpaRepository<User, UUID> {

    final QUser qUser = QUser.user;

    // How do I get the entityManager since this is a interface, i cannot have any variables?
    //@PersistenceContext
    //EntityManager entityManager;

    public default Optional<User> findByLogin(String login) {
        JPAQuery query = new JPAQuery(entityManager);
        User user = query
                .from(qUser)
                .where(
                        qUser.deleter.isNull(),
                        qUser.locked.isFalse(),
                        qUser.login.equalsIgnoreCase(login)
                )
                .singleResult(qUser);

        return Optional.ofNullable(user);
    }
}


推荐答案

默认方法只应用于委托对其他存储库方法的调用。默认方法 - 根据定义 - 无法访问实例的任何状态(因为接口没有)。它们只能委托给其他接口方法或者调用其他类的静态方法。

Default methods should only be used to delegate calls to other repository methods. Default methods - by definition - cannot access any state of an instance (as an interface has none). They only can delegate to other interface methods or call static ones of other classes.

实际上,使用参考文档是正确的方法。这是参考的简短版本(如果其他人也想知道):

Actually, using a custom implementation as described in the reference documentation is the right approach. Here's the short version for reference (in case others wonder, too):

/**
 * Interface for methods you want to implement manually.
 */
interface UserRepositoryCustom {
  Optional<User> findByLogin(String login);
}

/**
 * Implementation of exactly these methods.
 */
class UserRepositoryImpl extends QueryDslRepositorySupport implements UserRepositoryCustom {

  private static final QUser USER = QUser.user;

  @Override
  public Optional<User> findByLogin(String login) {

    return Optional.ofNullable(
      from(USER).
      where(
        USER.deleter.isNull(),
        USER.locked.isFalse(), 
        USER.login.equalsIgnoreCase(login)).
      singleResult(USER));
  }
}

/**
 * The main repository interface extending the custom one so that the manually
 * implemented methods get "pulled" into the API.
 */
public interface UserRepository extends UserRepositoryCustom, 
  CrudRepository<User, Long> { … }

请注意,命名约定在这里很重要(但可以根据需要进行自定义)。通过扩展 QueryDslRepositorySupport ,您可以从(...)方法访问,这样您就不必与 EntityManager 你自己。

Be aware that the naming conventions are important here (but can be customized if needed). By extending QueryDslRepositorySupport you get access to the from(…) method so that you don't have to interact with the EntityManager yourself.

或者你可以让 UserRepository 实施 QueryDslPredicateExecutor 并从存储库外部提交谓词,但这会让你最终得到需要使用Querydsl的客户端(这可能是不需要的)而且你不需要获取可选包装器类型OOTB。

Alternatively you can let UserRepository implement QueryDslPredicateExecutor and hand in the predicates from outside the repository but that'd let you end up with the clients needing to work with Querydsl (which might be unwanted) plus you don't get the Optional wrapper type OOTB.

这篇关于我应该使用Java 8默认方法来手动实现Spring Data存储库方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆