java 在 Spring Repository 中命名查询参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48515309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Naming query parameters in Spring Repository
提问by degath
This example works fine.
这个例子工作正常。
@Query("select t from TimeTable t where MONTH(t.date) = ?1 and YEAR(t.date) = ?2")
List<TimeTable> findAll(Integer month, Integer year);
Now I try to replace ?1 and ?2 with names like below
现在我尝试用下面的名称替换 ?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);
This one doesn't work and produce error:
这个不起作用并产生错误:
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
org.springframework.dao.InvalidDataAccessApiUsageException:具有该位置 [1] 的参数不存在;嵌套异常是 java.lang.IllegalArgumentException:具有该位置 [1] 的参数不存在
And this one
还有这个
@Query("select t from TimeTable t where MONTH(t.date) =:month and YEAR(t.date) =:year")
List<TimeTable> findAll(Integer month, Integer year);
produce error:
产生错误:
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.
org.springframework.dao.InvalidDataAccessApiUsageException:参数绑定的名称不能为空或空!在JDK < 8 上,您需要使用@Param 作为命名参数,在JDK 8 或更高版本上,请务必使用-parameters 进行编译。嵌套异常是 java.lang.IllegalArgumentException:参数绑定的名称不能为 null 或为空!在 JDK < 8 上,您需要使用 @Param 作为命名参数,在 JDK 8 或更高版本上,请务必使用 -parameters 进行编译。
UPDATE:
更新:
like an error above says I do not need to use @Param on JDK 8, but solution with @Param works:
就像上面的错误说我不需要在 JDK 8 上使用 @Param,但使用 @Param 的解决方案有效:
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
and when I delete @Params it goes this error again.
当我删除@Params 时,它再次出现此错误。
回答by Shafin Mahmud
Named Parameters using @Param
使用@Param 命名参数
Spring Data query parameters are replaced based on their positions. But this might go wrong and binding could be error prone. Hence it is suggested to use @Param
annotation in the method parameter to bind the query parameter names. And in the query, you need to use :paramName
to indicate that the same paramName
is to bind with the method parameter.
Spring Data 查询参数根据它们的位置被替换。但这可能会出错,并且绑定可能容易出错。因此建议@Param
在方法参数中使用注解来绑定查询参数名称。而在查询中,需要使用:paramName
来表示,同样paramName
是与方法参数绑定。
Update your method as below
更新您的方法如下
@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);
Simply its not possible to retain method parameter names for interface
根本不可能为接口保留方法参数名称
When a java class is compiled, by default java compiler changes the method parameter names. Say if you compile this code
编译 java 类时,默认情况下 java 编译器会更改方法参数名称。说如果你编译这段代码
public class Foo {
public void bar(int myHolyParam) {}
}
You might end up having this
你可能最终会得到这个
public class Foo {
public void bar(int arg0) {}
}
Your parameter names are lost. You may retain the names by setting a compiler flag like -g:vars
but this will only help for your Classes. Interface method parameter names can not be retained. There was no legit way to help this case before JDK 8 strikes. You can see this SO Questionon this regard.
您的参数名称丢失。您可以通过设置编译器标志来保留名称,-g:vars
但这只会对您的类有所帮助。接口方法参数名称不能保留。在 JDK 8 出现之前,没有合法的方法来帮助这个案例。您可以在这方面看到这个 SO Question。
on JDK 8 or better, be sure to compile with -parameters
在 JDK 8 或更高版本上,一定要编译 -parameters
Lately JDK 8 comes up with the solution. If you want to retain method parameter names (for Classes or Interfaces) you can simply tell compiler by setting -parameter
flag. Exploiting this JDK 8 feature, Spring can deduce the parameter names using reflection. But remember, still you need to use the compiler flag -parameters
to have this ability.
最近 JDK 8 提出了解决方案。如果您想保留方法参数名称(对于类或接口),您可以通过设置-parameter
标志简单地告诉编译器。利用 JDK 8 的这个特性,Spring 可以使用反射推导出参数名称。但是请记住,您仍然需要使用编译器标志-parameters
才能拥有此功能。
So if you are not using that flag or using java version less than 8, you must to use @Param
annotation to mark your parameters.
因此,如果您不使用该标志或使用低于 8 的 Java 版本,则必须使用@Param
注释来标记您的参数。
You can read a brief idea about Named Parameter in Java 8
您可以阅读有关Java 8 中的命名参数的简要介绍
回答by Jens Schauder
The first exception happens because you wrote =month
instead of =:month
. This way you only have one bind parameter but two method arguments which doesn't match.
第一个异常发生是因为您编写了=month
而不是=:month
. 这样,您只有一个绑定参数,但有两个不匹配的方法参数。
In the second case your byte code doesn't contain information about the names of the argument. Just do what the exception tells you to do:
在第二种情况下,您的字节码不包含有关参数名称的信息。只需按照异常告诉您的操作即可:
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.
参数绑定的名称不能为 null 或为空!在 JDK < 8 上,您需要使用 @Param 作为命名参数,在 JDK 8 或更高版本上,请务必使用 -parameters 进行编译。
Like this:
像这样:
@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);
If you are on Java 8 or above you can apply the other option given in the error message:
如果您使用的是 Java 8 或更高版本,则可以应用错误消息中给出的其他选项:
on JDK 8 or better, be sure to compile with -parameters
在 JDK 8 或更高版本上,请务必使用 -parameters 进行编译
If you do this you don't need the @Param
annotations.
如果这样做,则不需要@Param
注释。
See this question for background: Why are Spring Data repository method parameters names not available even on Java 8?
回答by krezus
please try this for last query.
请在最后一个查询中尝试此操作。
List<TimeTable> findAll(@Param("month") Integer month, @Param("year") Integer year);
based on this error:
基于此错误:
you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.
你需要对命名参数使用@Param,在 JDK 8 或更高版本上,一定要使用 -parameters 编译。
please check herefor your update question.
请在此处查看您的更新问题。