Spring Data JPA - 将列名和值作为参数传递

时间:2017-11-21 06:59:52

标签: hibernate spring-boot oracle11g spring-data-jpa jpql

我只是想知道如何在Spring Data JPA中将列名及其值传递给@Query注释。

基本上列名称将是静态的,我们过去常常将每个列作为元素放在Entity类中。但是在这里我想要一些不同的东西,这里的列名将是动态的,我将把这个值作为参数传递给存储库中定义的方法。

表格 - 日历

- id,PersonName,1,2,3 ...... 31

上面是表结构,1,2,3,..... 31是表示日历日的列名,我们在该列中有值。我使用Spring Data JPA从DB获取数据。 在这里,我只想获取特定日期的人名。 下面给出了在存储库中定义的函数。

@Query("select c from Calendar c where :calendarDay=:value")
List<Calendar> getPersonName(@Param("calendarDay") String calendarDay, @Param("value") String value);

这对我不起作用。 任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

Spring JPA支持的唯一动态参数是#{#entityName}。不支持@Query注释中的动态列名称,这就是您要完成的任务。

您唯一的选择是使用QueryDSL,规范或Criteria API手动构建查询,或者只是构建查询字符串并将其传递给EntityManager。无论如何,你必须为此编写代码。

例如见:

答案 1 :(得分:1)

看看sping data Specifications。你可以在那里找到你的解决方案!
阅读文档,您可以看到如果Calendar是您的域(我会尝试为我的域找到一个不同的名称,Java SE中已经有一个Calendar类),那么您可以使用类似的东西以上,

@Repository
public interface CalendarRepository extends JpaRepository<Calendar, Integer>, JpaSpecificationExecutor<Calendar> {
}


public class CalendarSpecification implements Specification<Calendar> {

    private String randomColumnName; // A varchar column.
    private String valueToSearchFor;

    public CalendarSpecification(String randomColumnName, String valueToSearchFor) {
        this.randomColumnName = randomColumnName;
        this.valueToSearchFor = valueToSearchFor;
    }

    @Override
    public Predicate toPredicate(Root<Calendar> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
        return builder.and(builder.equal(root.<String>get(this.randomColumnName), this.valueToSearchFor));
    }
}


@Service
public class CalendarService {

    @Autowired
    private CalendarRepository calendarRepository;

    public List<Calendar> findCustom(String randomColumnName, String valueToSearchFor) {
        CalendarSpecification cs = new CalendarSpecification(randomColumnName, valueToSearchFor);
        return calendarRepository.find(cs);
        // Or using lambda expression - without the need of CalendarSpecification class.
//      return calendarRepository.find((Root<ProductCategory> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
//          return builder.and(builder.equal(root.<String>get(randomColumnName), valueToSearchFor));
//      });
    }
}

答案 2 :(得分:0)

您可以像这样使用nativeQuery=true

@Query(value = "select c from Calendar c where c.:calendarDay=:value", nativeQuery = true)
List<Calendar> getPersonName(@Param("calendarDay") String calendarDay, @Param("value") String value);