JPA的最佳实践与Java8的可选返回?

前端之家收集整理的这篇文章主要介绍了JPA的最佳实践与Java8的可选返回?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我喜欢 Java8的语义我在我的DAO中使用了很多这样的代码
public Optional<User> findBy(String username) {
    try {
      return Optional.of(
        emp.get().createQuery("select u from User u where u.username = :username",User.class)
        .setParameter("username",username)
        .setMaxResults(1)
        .getSingleResult()
      );
    } catch (NoResultException e) {
      return Optional.empty();
    }
  }

它工作得很好,但是这样的代码(尝试捕获NoResultException)分散在我的DAO上.我必须抓住异常,这会降低性能.

我想知道它是否是最佳解决方案?或任何更好的解决方案,没有try-catch?

如果不可能(因为JPA中定义了NoResultException),任何“模板化”这种工作流的快捷方式?

谢谢.

解决方法

如果你可以模仿它,使用羊羔的魔法!

从@FunctionalInterface开始,定义lambda的合同:

@FunctionalInterface
public interface DaoRetriever<T> {
    T retrieve() throws NoResultException;
}

这是一个单一方法接口(或SMI),它将封装您的方法的行为.

现在创建一个使用SMI的实用方法

public static <T> Optional<T> findOrEmpty(final DaoRetriever<T> retriever) {
    try {
        return Optional.of(retriever.retrieve());
    } catch (NoResultException ex) {
        //log
    }
    return Optional.empty();
}

现在,在你的调用代码中使用import static,你的方法就是:

public Optional<User> findBy(String username) {
    return findOrEmpty(() ->
            emp.get().createQuery("select u from User u where u.username = :username",User.class)
                    .setParameter("username",username)
                    .setMaxResults(1)
                    .getSingleResult());
}

所以在这里,() – > emp.get()…是一个捕获检索行为的lambda.接口DaoRetriever被允许抛出NoResultException,所以lambda也是.

或者,我将使用TypedQuery的另一种方法 – getResultList – 并更改代码如下:

public Optional<User> findBy(String username) {
    return emp.get().createQuery("select u from User u where u.username = :username",User.class)
            .setParameter("username",username)
            .setMaxResults(1)
            .getResultList()
            .stream()
            .findFirst();
}

这具有更简单的优点,但是如果有的话,简单地丢弃其他结果的缺点.

猜你在找的Java相关文章