Java JPA标准API检查关联集合是否是另一个集合的子集

Java JPA标准API检查关联集合是否是另一个集合的子集,java,mysql,hibernate,spring-data-jpa,Java,Mysql,Hibernate,Spring Data Jpa,我有两个表:job和language。这两个表之间的关系是m:n,这意味着一个作业可能需要多种语言,而一种语言可能需要多种作业。所以我必须创建第三个名为job\u language的表来表示这种关系,它只包含两列job\u id(这是一个整数)和language\u code(例如英语的'eng',日语的'jap',等等)。我使用的数据库是MySQL 现在,我必须使用SpringDataJPA创建一个REST服务,以从用户输入中获取所有需要一组语言的作业,这些语言是另一组语言的子集。例如,假设我

我有两个表:
job
language
。这两个表之间的关系是m:n,这意味着一个作业可能需要多种语言,而一种语言可能需要多种作业。所以我必须创建第三个名为
job\u language
的表来表示这种关系,它只包含两列
job\u id
(这是一个整数)和
language\u code
(例如英语的
'eng'
,日语的
'jap'
,等等)。我使用的数据库是MySQL

现在,我必须使用SpringDataJPA创建一个REST服务,以从用户输入中获取所有需要一组语言的作业,这些语言是另一组语言的子集。例如,假设我有3个作业,其值在表
job\u language
中,如下所示:

--------------------------
| job_id | language_code |
--------------------------
| 1      | 'eng'         |
--------------------------
| 2      | 'eng'         |
--------------------------
| 2      | 'vie'         |
--------------------------
| 3      | 'jap'         |
--------------------------
| 3      | 'eng'         |
--------------------------
| 3      | 'vie'         |
--------------------------
现在用户想要查找需要
('eng','vie')
(这是根据用户输入创建的
语言代码的列表),查询应该返回两个作业:具有
作业id=1
的作业和具有
作业id=2
的作业

以下是我的实体类:

@Entity
public class Job {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ManyToMany
    @JoinTable(name = "job_language", 
        joinColumns = { @JoinColumn(name = "job_id", nullable = false) },
        inverseJoinColumns = { @JoinColumn(name = "language_code", nullable = false) })
    private List<Language> languages;

    // getters and setters here...
}

@Entity
public class Language { 
    @Id
    @Column(columnDefinition = "char", length = 3)
    private String code;

    @Column(length = 100)
    private String name;

    // getters and setters...
}

您可以将查询用作带有Spring数据存储库的本机SQL查询。例如:

public interface JobRepository extends JobRepository<Job, Long> {
  @Query(nativeQuery = true
      , value = "SELECT "
              + "  * "
              + "FROM"
              + "  job "
              + "WHERE "
              + "  id IN "
              + "  ( "
              + "  SELECT "
              + "    jl1.job_id "
              + "  FROM "
              + "    job_language jl1 "
              + "  LEFT JOIN "
              + "    job_language jl2 "
              + "  ON "
              + "    jl1.job_id = jl2.job_id "
              + "  AND jl1.language_code = jl2.language_code "
              + "  AND jl2.language_code IN ?1 "
              + "  GROUP BY "
              + "    jl1.job_id "
              + "  HAVING "
              + "    COUNT(jl1.language_code) = COUNT(jl2.language_code) "
              + "  )")
  List<Job> findAllByLanguageCodes(String... languageCodes);
}
公共接口JobRepository扩展了JobRepository{
@查询(nativeQuery=true)
,value=“选择”
+ "  * "
+“来自”
+“工作”
+“哪里”
+“中的id”
+ "  ( "
+“选择”
+“jl1.job_id”
+“来自”
+“作业语言jl1”
+“左连接”
+“作业语言jl2”
+“关于”
+“jl1.job\u id=jl2.job\u id”
+“和jl1.language_code=jl2.language_code”
+“和jl2.1中的语言代码”
+“分组依据”
+“jl1.job_id”
+“有”
+“计数(jl1.语言代码)=计数(jl2.语言代码)”
+ "  )")
列出findAllByLanguageCodes(字符串…语言代码);
}
使用本机查询的唯一标准是Spring数据应该能够将本机查询的返回值转换为带注释方法的返回类型。我们利用这一点,将
SELECT*FROM job
放在查询的顶部,这使得Spring数据JPA能够很好地处理结果,因为
job
映射到JPA实体(即使真正驱动查询的
job\u location
没有映射)


查看一个工作示例。

请查看这是否有帮助:@MatiasCaamaño不,这没有帮助,这个问题是关于检查一个字符串是否包含在另一个字符串中,但我的问题是关于检查关联集合是否是另一个集合的子集,可能我的问题不清楚,让我编辑它,请稍后查看。谢谢。Spring Data JPA不允许使用本机查询进行分页,这就是我放弃使用本机查询的原因,但现在我知道MySQL中有“limit”和“offset”关键字,本机查询是我问题的解决方案。谢谢你建议我使用本机查询,这样我可以再看一遍:)。分页查询使用
限制
偏移量
,所以你的思路是正确的。
public interface JobRepository extends JobRepository<Job, Long> {
  @Query(nativeQuery = true
      , value = "SELECT "
              + "  * "
              + "FROM"
              + "  job "
              + "WHERE "
              + "  id IN "
              + "  ( "
              + "  SELECT "
              + "    jl1.job_id "
              + "  FROM "
              + "    job_language jl1 "
              + "  LEFT JOIN "
              + "    job_language jl2 "
              + "  ON "
              + "    jl1.job_id = jl2.job_id "
              + "  AND jl1.language_code = jl2.language_code "
              + "  AND jl2.language_code IN ?1 "
              + "  GROUP BY "
              + "    jl1.job_id "
              + "  HAVING "
              + "    COUNT(jl1.language_code) = COUNT(jl2.language_code) "
              + "  )")
  List<Job> findAllByLanguageCodes(String... languageCodes);
}