【问题标题】:Spring Data JPA - Pass column name and value as parametersSpring Data JPA - 将列名和值作为参数传递
【发布时间】:2018-05-04 13:25:27
【问题描述】:

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

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

表格 - 日历

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

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

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

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

【问题讨论】:

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


【解决方案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】:

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

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

    参见,例如:

    【讨论】:

      【解决方案3】:

      也许你可以使用CASEWHEN

      SELECT 
         Id,
         PersonName,
      CASE
          WHEN ? = 'day_01' THEN day_01
          WHEN ? = 'day_02' THEN day_02
          WHEN ? = 'day_03' THEN day_03
          WHEN ? = 'day_04' THEN day_04
          WHEN ? = 'day_05' THEN day_05'
          ELSE 0
      END
       AS Value FROM Calendar
      

      Java 代码

      // customize entity
      public interface ITask {
          Long getId();
          String getName();
          String getValue();
      }
      
      @Repository
      public interface CalendarRepository {
          static final String CASE_WHEN = "\nCASE\n"
                  + "    WHEN :field = 'day_01' THEN day_01\n"
                  + "    WHEN :field = 'day_02' THEN day_02\n"
                  + "    WHEN :field = 'day_03' THEN day_03\n"
                  + "    WHEN :field = 'day_04' THEN day_04\n"
                  + "    WHEN :field = 'day_05' THEN day_05\n"
                  + "    ELSE 0\n"
                  + "END\n";
          
          @Query(nativeQuery = true, value = "SELECT Id, PersoneName, " + CASE_WHEN + " AS Value FROM Calendar WHERE field = :field")
          public List<ITask> findValues(@Param(value = "field") String field);
      }
      

      【讨论】:

        【解决方案4】:

        你可以像这样使用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);
        

        【讨论】:

        • 这似乎不起作用
        猜你喜欢
        • 1970-01-01
        • 2021-02-06
        • 2017-06-23
        • 2014-11-19
        • 2011-07-26
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        相关资源
        最近更新 更多