Hibernate JPQL多对多with in子句
我想知道是否有办法将本机查询转换为JPQL查询 询问Hibernate JPQL多对多with in子句,hibernate,jpa,spring-data-jpa,jpql,Hibernate,Jpa,Spring Data Jpa,Jpql,我想知道是否有办法将本机查询转换为JPQL查询 询问 public interface GraphJobRepository extends JpaRepository<GraphJob, Long> { @Query(value = "Select * From graph_job where id in (\n" + " SELECT distinct g.graph_job_id\n" + " FROM gr
public interface GraphJobRepository extends JpaRepository<GraphJob, Long> {
@Query(value = "Select * From graph_job where id in (\n" +
" SELECT distinct g.graph_job_id\n" +
" FROM graph_job_role g\n" +
" INNER JOIN clover_role r ON g.clover_role_id = r.role_id\n" +
" WHERE r.role_name in (:roles))",
nativeQuery = true)
List<GraphJob> findGraphJobsByRoles(@Param("roles") List<String> roles);
}
葡萄藤
@Entity
public class GraphJob {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@JoinTable(name = "graph_job_role", joinColumns = {
@JoinColumn(name = "graph_job_id")}, inverseJoinColumns = {
@JoinColumn(name = "clover_role_id")})
@ManyToMany
private Collection<CloverRole> roles;
}
@实体
公共类GraphJob{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@JoinTable(name=“graph\u job\u role”,joinColumns={
@JoinColumn(name=“graph\u job\u id”)},inverseJoinColumns={
@JoinColumn(name=“clover\u role\u id”)}
@许多
私人收藏角色;
}
我尝试过的任何方法都不起作用,我确信如果我要添加联接表实体,我可以让它工作,但我想知道是否有人知道如何在不实际创建该实体的情况下完成它 您可以通过这种方式尝试
操作符的成员、交叉连接和列表作为参数
@Query("select distinct j from GraphJob j, CloverRole r where r member of j.roles and r.roleName in(:roleNames)")
List<GraphJob> findGraphJobsByRoleNames(@Param("roleNames") List<String> roleNames);
@Query(“在(:roleNames)中选择不同于GraphJob j、CloverRole r的j.roles和r.roleName的r成员”)
列出findGraphJobsByRoleNames(@Param(“roleNames”)列出roleNames);
您可以通过这种方式尝试操作符的成员、交叉连接和列表作为参数
@Query("select distinct j from GraphJob j, CloverRole r where r member of j.roles and r.roleName in(:roleNames)")
List<GraphJob> findGraphJobsByRoleNames(@Param("roleNames") List<String> roleNames);
@Query(“在(:roleNames)中选择不同于GraphJob j、CloverRole r的j.roles和r.roleName的r成员”)
列出findGraphJobsByRoleNames(@Param(“roleNames”)列出roleNames);
如果您的目标是摆脱嵌入式字符串,那么您可以将其用于纯Java解决方案:
(无需更改现有代码)
public interface GraphJobRepository扩展了JpaRepository,
实体管理器供应商{
默认列表findGraphJobsByRoles(列表角色){
FluentQuery query=FluentJPA.SQL((GraphJob作业)->{
List jobIds=子查询((CloverRole r,
可接合图形角色)->{
选择(graphJobRole.getJoined().getId());
FROM(graphJobRole).JOIN(r)
.ON(GraphJob.inverseJoin(r,GraphJob::getRoles));
其中(roles.contains(r.getRoleName());
});
选择(作业);
来自(工作);
其中(jobIds.contains(job.getId());
});
返回query.createQuery(getEntityManager(),GraphJob.class).getResultList();
}
}
这将生成以下SQL:
SELECT t0.*
FROM graph_job t0
WHERE (t0.id IN (SELECT t2.graph_job_id
FROM graph_job_role t2 INNER JOIN clover_role t1 ON (t2.clover_role_id = t1.role_id)
WHERE (t1.role_name IN ?1 )) )
FluentJPA提供了第一类并提供了一个“虚拟的”。如果您的目标是摆脱嵌入式字符串,那么您可以将其用于纯Java解决方案:
(无需更改现有代码)
public interface GraphJobRepository扩展了JpaRepository,
实体管理器供应商{
默认列表findGraphJobsByRoles(列表角色){
FluentQuery query=FluentJPA.SQL((GraphJob作业)->{
List jobIds=子查询((CloverRole r,
可接合图形角色)->{
选择(graphJobRole.getJoined().getId());
FROM(graphJobRole).JOIN(r)
.ON(GraphJob.inverseJoin(r,GraphJob::getRoles));
其中(roles.contains(r.getRoleName());
});
选择(作业);
来自(工作);
其中(jobIds.contains(job.getId());
});
返回query.createQuery(getEntityManager(),GraphJob.class).getResultList();
}
}
这将生成以下SQL:
SELECT t0.*
FROM graph_job t0
WHERE (t0.id IN (SELECT t2.graph_job_id
FROM graph_job_role t2 INNER JOIN clover_role t1 ON (t2.clover_role_id = t1.role_id)
WHERE (t1.role_name IN ?1 )) )
FluentJPA提供了第一类并提供了一个“虚拟的”。看起来我仍然需要对Cloverole进行查询才能得到这些结果,所以我不确定这是否是一个更好的方法。角色列表最初来自身份验证原则。您可以按代码将所有CloverRoles存储在缓存中作为映射和do列表。另一个解决方案是将CloverRole从实体类更改为枚举。工作非常完美,这正是我想要的。谢谢。看来我还需要对CloverRole进行查询才能得到这些结果,所以我不确定这是否是一个更好的方法。角色列表最初来自身份验证原则。您可以按代码将所有CloverRoles存储在缓存中作为映射和do列表。另一个解决方案是将CloverRole从实体类更改为枚举。工作非常完美,这正是我想要的。谢谢