【问题标题】:How to use string_agg with PostgreSQL in @Query annotation without nativeQuery flag?如何在没有 nativeQuery 标志的 @Query 注释中将 string_agg 与 PostgreSQL 一起使用?
【发布时间】:2021-08-30 06:30:48
【问题描述】:

我需要从 @Query 注释中删除 nativaQuery 标志。
以后表结构可能会发生变化,不带nativeQuery的代码后面会更容易维护。

我有一个Parent 类,它通过@ManyToMany 注释链接到Child 类。 Child 类有一个字段 pseudonym,它是 String 类型的值。

查询的结果需要按照Child类中的String值排序,我必须对其进行排序,然后拼接成一个String值。

如果我不在 string_agg 函数中添加额外的排序,@Query 注释中没有 nativeQuery 标志的查询可以工作:
order by string_agg(c.pseudonym, ',')

如果我添加额外的所需排序如下,则会发生异常

  • order by string_agg(c.pseudonym, ',' order by c.pseudonym)
  • org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found 'order' near line 1, column ...
@Entity
@Getter
@Setter
@Table(name = "parent")
public class Parent {

    @Id
    private Long id;

    private String name;

    @ManyToMany
    @JoinTable(
            name = "parent_child_link",
            joinColumns = {@JoinColumn(name = "parent_id")},
            inverseJoinColumns = {@JoinColumn(name = "child_id")}
    )
    @OrderBy("pseudonym ASC")
    private List<Child> childs = new ArrayList<>();

}
@Entity
@Getter
@Setter
@Table(name = "child")
public class Child {

    @Id
    private Long id;

    private String pseudonym;

    @ManyToMany(mappedBy = "childs")
    private Set<Parent> parents = new HashSet<>();

}
public interface ParentRepository extends JpaRepository<Parent, Long> {

        @Query(nativeQuery = true, value =
            "select p.*" +
                    " from parent p" +
                    " left join parent_child_link link on p.id = link.parent_id" +
                    " left join child c on link.child_id = c.id" +
                    " where p.name = :name" +
                    " group by (p.id)" +
                    " order by string_agg(c.pseudonym, ',' order by c.pseudonym)")
    Page<Parent> find(@Param("name") String name, Pageable pageable);

}

【问题讨论】:

  • 如果你想使用 HQL/JPQL 不支持的原生功能,你必须编写原生查询。如果你想限制结果集,你也会得到原生查询,因为 HQL/JPQL 不支持 LIMIT
  • @Query 注释中可见的当前本机查询工作正常,并且在查询末尾的控制台(使用 p6spy 工具)中,您可以看到一个限制结果数量的添加条目@987654333 @.

标签: postgresql hibernate jpa spring-data-jpa


【解决方案1】:

请尝试嵌套查询:

select p.*
from (
    select p, string_agg(c.pseudonym, ',' order by c.pseudonym) ord
    from parent p
    left join parent_child_link link on p.id = link.parent_id
    left join child c on link.child_id = c.id
    where p.name = :name
    group by (p.id)
) inn(p, ord)
order by ord

或:

select p.*
from(
    select p, c.pseudonym
    from parent p
    left join parent_child_link link on p.id = link.parent_id
    left join child c on link.child_id = c.id
    where p.name = :name
    order by p, pseudonym
) inn(p, pseudonym)
group by p.id
order by string_agg(pseudonym, ',')

【讨论】:

  • 上述查询将无助于从@Query 注解中删除 nativeQuery 标志。
  • @GrzegorzKawalec 当然不会...您正在使用 postgres 特定功能...
猜你喜欢
  • 2015-05-11
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2016-07-01
  • 1970-01-01
相关资源
最近更新 更多