spring-data-jpa 如何使用集值命名参数创建动态查询?

kjthegm6  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(204)

如标题所示,我目前正尝试使用集值命名参数(:queryLst)向JPQL查询添加部件。

函数调用:

List<PanelSet> psetLst = setRepository.getMaxZchnrGroupByLeftEight(p.getCustomerNumber(), p.getDrawingNumber(), queryLst);

查询列表:

// Is used to store values from scanned and convert them into parts of a query
ArrayList<String> queryLst = new ArrayList<>();
for (int i = 0; i < size1; i++) {
    scanEdvRev = scanned.get(i).toString();
    queryLst.set(i, "and left(a.drawingnumber, 8) != left('" + scanEdvRev + "', 8)");
}

设置存储库:

public interface SetRepository extends CrudRepository<PanelSet, Integer> {

@Query("select distinct max(a.drawingNumber) from PanelSet a "
        + "where a.customerNumber = :customerNumber "
        + "and a.drawingNumber != :drawingNumber (:queryLst) "
        + "group by left(a.drawingNumber, 8)")
List<PanelSet> getMaxZchnrGroupByLeftEight(@Param("customerNumber") String customerNumber, 
        @Param("drawingNumber") String drawingNumber, 
        @Param("queryLst") ArrayList<String> queryLst);
}

运行项目时出现以下异常:

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 159 [select distinct max(a.drawingNumber) from com.asetronics.qis2.model.PanelSet a where a.customerNumber = :customerNumber and a.drawingNumber != :drawingNumber (:queryLst) group by left(a.drawingNumber, 8)]
我不确定我解决这个问题的方法是否正确,也不确定这个异常是由简单的语法错误引起的,还是由我使用集值命名参数引起的。
我已经按照this指南尝试解决这个问题。
编辑:我基本上是尝试将ArrayList<String> queryLst中的每个String添加到setRepository中的参数化查询中。

@Query("select distinct max(a.drawingNumber) from PanelSet a "
    + "where a.customerNumber = :customerNumber "
    + "and a.drawingNumber != :drawingNumber (:queryLst) "
    + "group by left(a.drawingNumber, 8)")

如果成功,则查询后面的函数

List<PanelSet> getMaxZchnrGroupByLeftEight(@Param("customerNumber") String customerNumber, 
            @Param("drawingNumber") String drawingNumber, 
            @Param("queryLst") ArrayList<String> queryLst);

应如下所示:

queryStr = "select distinct max(a.drawingNumber) from PanelSet a "
    + "where a.customerNumber = " + customerNumber + ""
    + "and a.drawingNumber != " + drawingNumber + "";
for (String s : queryLst) {
    queryStr = queryStr + s;
}
queryStr = queryStr + " group by left(a.drawingNumber, 8)";

我希望这能澄清我想用queryLst做什么。

3yhwsihp

3yhwsihp1#

使用传入查询块列表的方法无法实现这一点。
最接近的方法是将每个可能的条件添加到查询中,并以允许忽略条件的方式为所有这些条件提供值,通常是通过提供空值。
您的程式码可能如下所示:

@Query("select distinct max(a.drawingNumber) from PanelSet a "
    + "where a.customerNumber = :customerNumber "
    + "and a.drawingNumber != :drawingNumber "
    + "and a.myTextColumn = coalesce(:myTextColumn, a.myTextColumn) "
    + "and a.myIntegerColumn = coalesce(:myIntegerColumn, a.myIntegerColumn) "
    // etc for all possible runtime conditions
    + "group by left(a.drawingNumber, 8)")
List<PanelSet> getMaxZchnrGroupByLeftEight(
    @Param("customerNumber") String customerNumber, 
    @Param("drawingNumber") String drawingNumber, 
    @Param("myTextColumn") String myTextColumn,
    @Param("myIntegerColumn") Integer myIntegerColumn);

myTextColumnmyIntegerColumn传递null将允许该列为任何值(null除外)。
您必须找到适用于您所拥有的条件类型、所涉及的列的数据类型以及是否允许空值的SQL。
如果传递空值不起作用,则使用特殊值,文本列可能为空,一些“不可能”的日期(如2999-01-01 fir date columns等),并编写如下条件:

and (a.myCol = :myCol or :myCol = '2999-01-01')

相关问题