【问题标题】:Why need @Query when I can write a method in Spring JPA当我可以在 Spring JPA 中编写方法时为什么需要 @Query
【发布时间】:2017-06-20 12:07:14
【问题描述】:

我刚刚开始使用 Spring JPA,并且正在查看我的同事编写的代码。 我看到他一直在使用以下代码使用用户名查找登录对象:

public interface LoginDao extends JpaRepository<Login, Long> {
        @Query("SELECT u FROM Login u WHERE LOWER(u.username) = LOWER(:username)")
        Login findByUsername(@Param("username") String username);
}

他不能像这样创建一个方法:

@GET
@Path("{username}")
public Login getOne(@PathParam("username") String username) {
    Login login = loginDao.findOne(username);
    if (login == null) {
        throw new WebApplicationException(Response.Status.NOT_FOUND);
    } else {
        return login;
    }
}

使用@Query 而不是编写方法方法的根本优势是什么。还是我完全错了,两者都有不同的目的。

我个人不想在代码中编写查询。我认为将 java 与 sql 查询混合在一起会使代码看起来更难看。

我们的堆栈是 java、JPA、Jersey、JAX-RS、Postgreql、Spring Boot、Hibernate

问候

【问题讨论】:

  • 该查询不仅仅只是一个简单的findOne,在这种情况下它不会起作用,因为findOne 需要一个id 而不是任意值。
  • 我会更新我的问题,因为你是对的 findOne 只需要 id

标签: java spring hibernate spring-data-jpa jpql


【解决方案1】:

首先,这不是 SQL 查询,这是 JPQL 查询。如果nativeQuery 属性设置为true,这将是一个本机 SQL 查询,默认情况下并非如此。

使用 JPQL 创建查询非常好,您将能够毫无问题地从 Hibernate 切换到 Eclipse Link 或其他 JPA 实现。您还应该能够从 Postgres 切换到 MySQL、SQL Server...

如果您的同事使用@Query(nativeQuery = true, value = "...") 创建查询,您必须开始担心,否则对我来说看起来很好。

其次,当您查看存储库声明时,您可以看到 Login 实体的 ID 字段的类型为 Long。这意味着loginDao.findOne(..) 方法需要一个Long 参数。可能不是username 的代理键。

这就是您的同事创建此新方法的原因:通过Long 代理键以外的其他内容查找Login 行。 (这里的用户名很可能是业务密钥,但我不知道您的应用程序。)


仅供参考:Spring 自动创建带有存储库方法签名的查询(派生查询)。例如:

public interface LoginDao extends JpaRepository<Login, Long> {
    Login findByUsername(String username);
}

Spring JPA 将自动创建一个查询以查找名为 username 的字段,并使用它创建一个 WHERE 子句。

请注意,它与您的同事查询相同,因为它不会使用 LOWER 函数。

JPA 文档中关于这些派生查询的一些锚点:


关于你的标题的另一件事:

“当我可以在 Spring JPA 中编写方法时为什么需要 @Query”

这个@Query 在 Spring JPA 中编写了一个方法。 :^)

【讨论】:

  • 非常好的答案。现在我很清楚了。非常感谢。
  • 太棒了,链接共享 ;)
【解决方案2】:

JPARepository 提出了一些受支持的关键字,它们将根据您的实体自行编写查询。

如果我们从 JPARepository 提供的东西中寻找开箱即用的东西,@Query 很有用 - 加入多个查询、编写本机查询等。

从你的代码 sn-p 两者都会做同样的事情

有关更多信息,您可以参考 - https://docs.spring.io/spring-data/jpa/docs/1.4.2.RELEASE/reference/html/jpa.repositories.html

【讨论】:

    猜你喜欢
    • 2022-10-16
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多