当我可以在 Spring JPA 中编写方法时,为什么需要 @Query
Why need @Query when I can write a method in Spring JPA
我刚开始使用 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
此致
首先,这不是 SQL 查询,这是一个 JPQL 查询。如果 nativeQuery
属性设置为 true
,这将是本机 SQL 查询,默认情况下并非如此。
使用 JPQL 创建查询非常好,您可以从 Hibernate 切换到 Eclipse Link 或其他 JPA 实现而不会出现问题。您还应该能够从 Postgres 切换到 MySQL、SQL 服务器...
如果您的同事使用 @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 文档中关于那些派生查询的一些锚点:
- https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods
- https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords
关于您的标题的另一件事:
"Why need @Query when I can write a method in Spring JPA"
好吧,这个 @Query
在 Spring JPA 中编写了一个方法。 :^)
JPARepository
提出了一些受支持的关键字,这些关键字将根据您的实体自行编写查询。
如果我们正在寻找 JPARepository 提供的开箱即用的东西,@Query
很有用,例如 - 连接多个查询、编写本机查询等。
从你的代码片段来看,两者都会做同样的事情
更多信息可以参考-https://docs.spring.io/spring-data/jpa/docs/1.4.2.RELEASE/reference/html/jpa.repositories.html
我刚开始使用 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
此致
首先,这不是 SQL 查询,这是一个 JPQL 查询。如果 nativeQuery
属性设置为 true
,这将是本机 SQL 查询,默认情况下并非如此。
使用 JPQL 创建查询非常好,您可以从 Hibernate 切换到 Eclipse Link 或其他 JPA 实现而不会出现问题。您还应该能够从 Postgres 切换到 MySQL、SQL 服务器...
如果您的同事使用 @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 文档中关于那些派生查询的一些锚点:
- https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods
- https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords
关于您的标题的另一件事:
"Why need @Query when I can write a method in Spring JPA"
好吧,这个 @Query
在 Spring JPA 中编写了一个方法。 :^)
JPARepository
提出了一些受支持的关键字,这些关键字将根据您的实体自行编写查询。
如果我们正在寻找 JPARepository 提供的开箱即用的东西,@Query
很有用,例如 - 连接多个查询、编写本机查询等。
从你的代码片段来看,两者都会做同样的事情
更多信息可以参考-https://docs.spring.io/spring-data/jpa/docs/1.4.2.RELEASE/reference/html/jpa.repositories.html