JPQL-Spring Boot存储库查询-Map属性

时间:2018-09-26 07:40:36

标签: sql spring-boot spring-data-jpa jpql

我的域类中有一个map属性,并且尝试在存储库中创建查询或使用默认的“ 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[$1] = $2")
    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'

enter image description here

1 个答案:

答案 0 :(得分:1)

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

    @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);
}

要在选择中检索COLLECTOR_ATTRIBUTES,我们可以在@NamedEntityGraph类和存储库方法中定义一个Collector,如下所示

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

并使用存储库方法报告@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);