我有以下ManyToMany映射。
@Entity
public class Class1 {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "class1_class2", joinColumns = @JoinColumn(name = "class1Id"), inverseJoinColumns = @JoinColumn(name = "class2Id"))
private List<Class2> class2;
}
@Entity
public class Class2 {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
}
我想检索与Classe2实体有关系的所有Class1实体,class2Id = 1,class2Id = 2,class2Id = 3。 {1,2,3}
或者要过滤其class2 List上的Classe1实体,Class2实体的值为:class2Id = 1且class2Id = 2且class2Id = 3
例如:
如果在联接表上,我有以下值。
class1Id class2Id
1 1
1 2
1 3
1 4
6 1
6 2
6 3
4 1
5 2
结果将是这个例子,Class1 with class1Id:1和6。 因为Class1Id = 1的Class1实体与classe2Id:1,2,3,4相关 Class1Id = 2的Class1实体与classe2Id:1,2,3
有关系是否可以通过JPA2(谓词)返回正确的实体?
还有更好的映射来处理这种情况吗?
目前,我已经提出了以下SQL查询:
select v1.class1Id from class1_class2 v1
inner join class1_class2 v2 on v1.class1Id=v2.class1Id
inner join class1_class2 v3 on v2.class1Id=v3.class1Id
where v1.classe2Id=1 and v2.classe2Id=2 and v3.classe2Id=3;
答案 0 :(得分:4)
以下是可以提供帮助的查询:
select c1
from Class1 c1
join c1.class2 c2
where c2.id in (1,2,3)
group by c1
having count(c1)=3 ;
答案 1 :(得分:3)
首先在您的班级 Class2 中,您需要添加以下内容:
@ManyToMany(fetch = FetchType.LAZY, mappedBy="class2")
private List<Class1> class1;
在此之后,您的任务应该使用此查询完成:
select c1 from Class1 c1 join c1.class2 c2 where c2.id in ?1 group by c1
where?1 - List<Long>
类型的对象,包含ids {1,2,3}
。
答案 2 :(得分:1)
还有一些部分不是很清楚,因为我没有看到连接表值中的class1Id = 2或者class1Id = 6只有class2Id = 1。但无论如何,我会给你类似的谓词映射示例,以便您可以根据自己的需要进行修改。我使用过StaticMetaModels。您可以将它们移动到实体类的同一个包中。我无法进行测试,但我相信这可能是一个很好的路线图。
JPA 2.0查询:
CriteriaBuilder criteriaBuilder = getEm().getCriteriaBuilder();
CriteriaQuery<Class1> criteriaQuery = criteriaBuilder.createQuery(Class1.class);
Root<Class1> fromClass1 = criteriaQuery.from(Class1.class);
List<Predicate> conditions = new ArrayList<Predicate>();
Subquery<Class2> qry = criteriaQuery.subquery(Class2.class);
Root<Class2> fromClass2 = qry.from(Class2.class);
qry.select(fromClass2);
qry.where(criteriaBuilder.equal(fromClass2.get(Class2_.getId()), idParamGoesHere));
conditions.add(criteriaBuilder.in(.get(Class1_.getClass2()).value(qry));
criteriaQuery.where(conditions.toArray(new Predicate[0]));
TypedQuery<Class1> query = getEm().createQuery(criteriaQuery);
List<Class1> results = query.getResultList();
StaticMetaModel Class1:(此案例不需要,但我已添加)
@StaticMetamodel(Class1.class)
public class Class1_ {
private static volatile SingularAttribute<Class1, Long> id;
private static volatile SingularAttribute<Class1, Class2> class2;
public static SingularAttribute<Class1, Long> getId() {
return id;
}
public static void setId(SingularAttribute<Class1, Long> id) {
Class1_.id = id;
}
public static SingularAttribute<Class1, Class2> getClass2() {
return class2;
}
public static void setClass2(SingularAttribute<Class1, Class2> class2) {
Class1_.class2 = class2;
}
}
StaticMetaModel Class2:
@StaticMetamodel(Class2.class)
public class Class2_ {
private static volatile SingularAttribute<Class2, Long> id;
public static SingularAttribute<Class2, Long> getId() {
return id;
}
public static void setId(SingularAttribute<Class2, Long> id) {
Class2_.id = id;
}
}