有没有一种方法可以在Spring应用程序中参数化@Query值?

时间:2019-07-12 19:47:04

标签: java spring spring-boot

我正在使用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注释。那么我该如何参数化呢?想法?

1 个答案:

答案 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);
   }
//...
}