我正在使用PostGreSQL在Spring应用程序的@Query注释内编写一个插入查询。因此,我正在我编写的接口内扩展CRUD存储库。
@Repository
public interface PostGreRepository extends CrudRepository<FoodDetails,Long> {
@Modifying
@Query(value="insert into fooddetails(person_id,food_desc) select id,food_desc from person,food where id = " +
"person_id",nativeQuery = true)
void insertIntoPostGre();
}
现在,我需要将查询保留为应用程序中的参数,因为它以后可能会更改。我不能在接口内使用@Value注释。那么我该如何参数化呢?想法?
答案 0 :(得分:1)
作为一个想法,使用反射来更改注释值:
免责声明:changeAnnotationValue
方法取自here,我自己没有运行过
@SuppressWarnings("unchecked")
public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue){
Object handler = Proxy.getInvocationHandler(annotation);
Field f;
try {
f = handler.getClass().getDeclaredField("memberValues");
} catch (NoSuchFieldException | SecurityException e) {
throw new IllegalStateException(e);
}
f.setAccessible(true);
Map<String, Object> memberValues;
try {
memberValues = (Map<String, Object>) f.get(handler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
Object oldValue = memberValues.get(key);
if (oldValue == null || oldValue.getClass() != newValue.getClass()) {
throw new IllegalArgumentException();
}
memberValues.put(key,newValue);
return oldValue;
}
使用查询作为参数:
@Component
public class PostGreRepositoryParameterizer {
//...
@Value("query")
private String query;
public void modify() {
Method method = PostGreRepository.class.getMethod("insertIntoPostGre");
final Query queryAnnotation = method.getAnnotation(Query.class);
changeAnnotationValue(queryAnnotation, "value", query);
}
//...
}