【问题标题】:Is there a way to make a spring data jpa query in order to see if a string contains any other string in a list?有没有办法进行 spring data jpa 查询以查看字符串是否包含列表中的任何其他字符串?
【发布时间】:2021-11-03 22:21:34
【问题描述】:

所以我正在做一个项目,我们有一个“主题”机制,实际上非常类似于堆栈溢出的机制。 因此,我将每个实体(烹饪食谱)保存为一个包含逗号分隔字符串的主题变量。现在我的大问题是我需要findByTopics,就像在多个主题中一样。我试过@Query

@Query("select new com.fullstack.dtos.projections.LocalizedRecipe(t.id, t.created, t.createdBy, t.lastModified, t.lastModifiedBy, t.version, l.title, l.description) from tutorial t inner join t.localizations l where l.id.locale = :lang and t.topics in :topics")
Page<LocalizedRecipe> findAllByTopics(String lang, Set<String> topics, Pageable page);

我什至更改了我的模型,以便主题是字符串的@ElementCollection,尝试使用相同的查询,但总是会出现类型错误。大多数时候它会抛出:

java.lang.IllegalArgumentException: Parameter value [Java] did not match expected type [java.util.Set (n/a)]

我的问题是如何做到这一点。改变我的模型不是问题,我只是似乎找不到一个好的方法。

当前型号:

public class RecipeDAO {

@Id
    @GeneratedValue(generator = "uuid2", strategy = GenerationType.AUTO)
    @Column(columnDefinition = "BINARY(16)", unique = true)
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    private UUID id;

    @CreatedDate
    private LocalDateTime created;

    @CreatedBy
    private String createdBy;

    @LastModifiedDate
    private LocalDateTime lastModified;

    @LastModifiedBy
    private String lastModifiedBy;

    @Version
    private Integer version;

    private Boolean visible;

    private String topics;

    @MapKey(name = "id.locale")
    @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true)
    private Map<String, Localization> localizations;
}

我在这里的最终目标是能够检查是否有 3 个主题为“早餐、午餐、晚餐”的食谱。我希望能够使用 ["lunch", "dinner"] 找到ByTopics,它会返回那些,返回所有在主题字符串中吃晚餐或午餐的人 基本上是一个子字符串匹配器。或者实现这一目标的替代方法,正如我所说,改变模型不是问题

编辑:我也尝试更改为 List 并成为 @ElementCollection 但出现错误。我不知道我是否可以看到这两个列表是否相交。

【问题讨论】:

  • 首先,您当前的模型尚不清楚。请分享。
  • 另外请分享存储库方法以及您传递给过滤器的参数是什么?是字符串还是列表?
  • 我已编辑以包含当前模型。
  • 它是一个集合,如果需要,可以是一个列表,甚至可以是一个 java 数组/可变参数。我的问题是如何进行查询。我想看看对象的“topics”参数是否有集合中的任何字符串。
  • 您可以检查thorben-janssen.com/hibernate-tips-query-elementcollection 并且按照其他人的建议使用方法名称也应该可以工作

标签: java spring-boot spring-data-jpa spring-data


【解决方案1】:

您应该可以使用In 关键字来做到这一点,如下所示:

findByTopicsIn(Collection<String> topics)

【讨论】:

    【解决方案2】:
    1. 在存储库中,您可以使用派生查询方法,其中每个 parameter 引用相应实体的 properties - 例如

      findByTopicsOrTopics(String topic1, String topic2);

    对应的sql查询-

    select * from RecipeDAO where topics="topic1" OR topics="topic2";
    
    1. 如果主题的数量更多,那么在方法中使用主题集合作为参数比将每个主题作为单独的参数传递更好。。李>

    提供反对使用In的主题集合

    List<RecipeDAO> findByTopicsIn(Collection<String> topics);
    

    对应的sql查询-

    select * from RecipeDAO where topics in('topics1','topics2',...,'topicsn');
    

    【讨论】:

    • 我知道,但我不知道有多少主题即将到来。可能是 1 可能是 2 可能是 10
    • 然后你可以通过提供主题集合来使用派生的查询方法反对使用 In List&lt;RecipeDAO&gt; findByTopicsIn(Collection&lt;String&gt; topics);
    • 这在我的示例中有效吗?我需要将主题更改为字符串 @ElementCollection 正确吗?
    猜你喜欢
    • 2013-12-04
    • 2016-09-20
    • 2019-01-04
    • 2011-03-30
    • 2011-05-14
    • 2018-08-27
    • 2016-08-29
    • 2017-09-11
    • 2016-01-27
    相关资源
    最近更新 更多