在 Spring 存储库中命名查询参数
Naming query parameters in Spring Repository
这个例子工作正常。
@Query("select t from TimeTable t where MONTH(t.date) = ?1 and YEAR(t.date) = ?2")
List<TimeTable> findAll(Integer month, Integer year);
现在我尝试将 ?1 和 ?2 替换为如下名称
@Query("select t from TimeTable t where MONTH(t.date) =month and YEAR(t.date) =:year")
List<TimeTable> findAll(Integer month, Integer year);
这个不起作用并产生错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter
with that position [1] did not exist; nested exception is
java.lang.IllegalArgumentException: Parameter with that position [1]
did not exist
还有这个
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(Integer month, Integer year);
产生错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Name for
parameter binding must not be null or empty! On JDKs < 8, you need to
use @Param for named parameters, on JDK 8 or better, be sure to
compile with -parameters.; nested exception is
java.lang.IllegalArgumentException: Name for parameter binding must
not be null or empty! On JDKs < 8, you need to use @Param for named
parameters, on JDK 8 or better, be sure to compile with -parameters.
更新:
就像上面的错误说我不需要在 JDK 8 上使用 @Param,但是使用 @Param 的解决方案有效:
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
当我删除@Params 时,它再次出现此错误。
请在最后一个查询中尝试这个。
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
基于此错误:
you need to use @Param for named parameters, on JDK 8 or better, be
sure to compile with -parameters.
请检查 了解您的更新问题。
第一个异常发生是因为您写了 =month
而不是 =:month
。这样你只有一个绑定参数但是两个不匹配的方法参数。
在第二种情况下,您的字节代码不包含有关参数名称的信息。只做异常告诉你做的事:
Name for parameter binding must not be null or empty!
On JDKs < 8, you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.
像这样:
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
如果您使用 Java 8 或更高版本,您可以应用错误消息中给出的其他选项:
on JDK 8 or better, be sure to compile with -parameters
如果您这样做,则不需要 @Param
注释。
查看此问题了解背景:
使用@Param 命名参数
Spring 数据查询参数根据位置替换。但这可能会出错并且绑定可能容易出错。因此建议在方法参数中使用@Param
注解来绑定查询参数名。并且在查询中需要用:paramName
来表示同样的paramName
是要和方法参数绑定
如下更新您的方法
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
根本无法保留接口的方法参数名称
编译 java class 时,默认情况下 java 编译器会更改方法参数名称。假设你编译这段代码
public class Foo {
public void bar(int myHolyParam) {}
}
你最终可能会得到这个
public class Foo {
public void bar(int arg0) {}
}
您的参数名称已丢失。您可以通过设置像 -g:vars
这样的编译器标志来保留名称,但这只会对您的 类 有所帮助。接口方法参数名不能保留。在 JDK 8 次罢工之前,没有合法的方法来帮助这个案子。你可以在这方面看到这个SO Question。
on JDK 8 或更好,一定要用 -parameters
编译
最近JDK8提出了解决方案。如果您想保留方法参数名称(对于 类 或接口),您可以通过设置 -parameter
标志简单地告诉编译器。利用此 JDK 8 功能,Spring 可以使用反射推导出参数名称。但请记住,您仍然需要使用编译器标志 -parameters
才能拥有此功能。
因此,如果您不使用该标志或使用 java 小于 8 的版本,则必须使用 @Param
注释来标记您的参数。
您可以阅读有关 Named Parameter in Java 8
的简要想法
这个例子工作正常。
@Query("select t from TimeTable t where MONTH(t.date) = ?1 and YEAR(t.date) = ?2")
List<TimeTable> findAll(Integer month, Integer year);
现在我尝试将 ?1 和 ?2 替换为如下名称
@Query("select t from TimeTable t where MONTH(t.date) =month and YEAR(t.date) =:year")
List<TimeTable> findAll(Integer month, Integer year);
这个不起作用并产生错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter with that position [1] did not exist; nested exception is java.lang.IllegalArgumentException: Parameter with that position [1] did not exist
还有这个
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(Integer month, Integer year);
产生错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Name for parameter binding must not be null or empty! On JDKs < 8, you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.; nested exception is java.lang.IllegalArgumentException: Name for parameter binding must not be null or empty! On JDKs < 8, you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.
更新:
就像上面的错误说我不需要在 JDK 8 上使用 @Param,但是使用 @Param 的解决方案有效:
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
当我删除@Params 时,它再次出现此错误。
请在最后一个查询中尝试这个。
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
基于此错误:
you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.
请检查
第一个异常发生是因为您写了 =month
而不是 =:month
。这样你只有一个绑定参数但是两个不匹配的方法参数。
在第二种情况下,您的字节代码不包含有关参数名称的信息。只做异常告诉你做的事:
Name for parameter binding must not be null or empty! On JDKs < 8, you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.
像这样:
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
如果您使用 Java 8 或更高版本,您可以应用错误消息中给出的其他选项:
on JDK 8 or better, be sure to compile with -parameters
如果您这样做,则不需要 @Param
注释。
查看此问题了解背景:
使用@Param 命名参数
Spring 数据查询参数根据位置替换。但这可能会出错并且绑定可能容易出错。因此建议在方法参数中使用@Param
注解来绑定查询参数名。并且在查询中需要用:paramName
来表示同样的paramName
是要和方法参数绑定
如下更新您的方法
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
根本无法保留接口的方法参数名称
编译 java class 时,默认情况下 java 编译器会更改方法参数名称。假设你编译这段代码
public class Foo {
public void bar(int myHolyParam) {}
}
你最终可能会得到这个
public class Foo {
public void bar(int arg0) {}
}
您的参数名称已丢失。您可以通过设置像 -g:vars
这样的编译器标志来保留名称,但这只会对您的 类 有所帮助。接口方法参数名不能保留。在 JDK 8 次罢工之前,没有合法的方法来帮助这个案子。你可以在这方面看到这个SO Question。
on JDK 8 或更好,一定要用 -parameters
编译
最近JDK8提出了解决方案。如果您想保留方法参数名称(对于 类 或接口),您可以通过设置 -parameter
标志简单地告诉编译器。利用此 JDK 8 功能,Spring 可以使用反射推导出参数名称。但请记住,您仍然需要使用编译器标志 -parameters
才能拥有此功能。
因此,如果您不使用该标志或使用 java 小于 8 的版本,则必须使用 @Param
注释来标记您的参数。
您可以阅读有关 Named Parameter in Java 8
的简要想法