JPQL - Spring 引导存储库查询 - 映射 属性

JPQL - Spring Boot Repository Query - Map Property

我的域 class 中有一个映射 属性,我正在尝试在存储库中创建查询或使用默认的 "findByBlah" 语法来提取 属性 来自数据库。目前不会工作。我可以轻松地在 SQL 中编写查询,但我不知道 JPQL 期望什么。如何使用 JPQL 或接口 "findBy" 语法从数据库中提取这些数据?无论我当前使用哪种存储库方法,当它从数据库中提取 "Collector" 时,属性(复杂对象的映射或列表)始终为空。

域对象:

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "collector")
public class Collector {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "collector_id")
    private Long id;

    @NotNull
    private String name;

    @ElementCollection
    @MapKeyColumn(name = "attribute_name")
    @Column(name = "attribute_value")
    @CollectionTable(name = "collector_attributes", joinColumns = @JoinColumn(name = "collector_id"))
    private Map<String, String> attributes;

    @Override
    public String toString() {
        return ObjectUtil.print(this);
    }
}

存储库:

public interface CollectorRepository extends PagingAndSortingRepository<Collector, Long> {

    @Query(value = "select c from Collector c where c.attributes[] = ")
    Page<Collector> findByAttributesNameAndValue(String name, String value, Pageable pageable);
}

这是在 H2 控制台中运行的查询:

SELECT * FROM Collector a INNER JOIN collector_attributes b ON a.collector_id = b.collector_id where b.attribute_name= 'nickName' and b.attribute_value  = 'Critikon'

唯一对我有用的是定义对象关系而不是映射:

    @ElementCollection
    @CollectionTable(name = "COLLECTOR_ATTRIBUTES", joinColumns = @JoinColumn(name = "COLLECTOR_ID"))
    private List<CollectorAttribute> attributes;

和嵌入对象

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Embeddable
public class CollectorAttribute {

    @Column(name = "ATTRIBUTE_NAME")
    private String key;

    @Column(name = "ATTRIBUTE_VALUE")
    private String value;
}

现在您可以使用嵌入对象的属性进行查询

public interface CollectorRepository extends JpaRepository<Collector, Long> {
    List<Collector> findByAttributesKeyAndAttributesValue(String key, String value);
}

要在 select 中检索 COLLECTOR_ATTRIBUTES 我们可以在 Collector class 中定义一个 @NamedEntityGraph 和存储库方法如下

@NamedEntityGraph(name = "Collector.attributes",
    attributeNodes = @NamedAttributeNode("attributes"))
@Entity
@Table(name = "COLLECTOR")
public class Collector {

并在 Repository 方法中报告 @EntityGraph

public interface CollectorRepository extends JpaRepository<Collector, Long> {

    @EntityGraph(value = "Collector.attributes", type = EntityGraph.EntityGraphType.LOAD)
    List<Collector> findByAttributesKeyAndAttributesValue(String key, String value);
    }
}

现在你也有属性了

如果你想在其他方法上也加载属性,你必须使用@EntityGraph

@EntityGraph(value = "Collector.attributes", type = EntityGraph.EntityGraphType.LOAD)
Optional<Collector> findById(Long var1);