JPA2 条件查询 select 中 Table A 中的记录,其引用在 Table B 中未找到
JPA2 Criteria Query to select records in Table A whose reference is not found in Table B
我有以下table结构如下
Table A {
id <-- Primary key
someColumn
}
Table B {
id <-- Primary key
someColumn
idOfA <-- Foreign key mapping to Table A
}
实体类如下所示
@Entity
@Table(name = "A")
public class A implements Serializable {
private static final long serialVersionUID = -78448557049178402L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
.......
.......
@OneToMany(mappedBy = "a")
private List<B> bs = new ArrayList<>();
}
@Entity
@Table(name = "B")
public class B implements Serializable {
private static final long serialVersionUID = -659500557015441771L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
.......
.......
@OneToOne
@JoinColumn(name = "a_id", nullable = false)
private A a;
}
使用 JPA2,我想 select 来自 table A 的记录在 Table B 中没有引用
预期的本机 postgres 查询是
select * from A a
where a.id not in
(select b.idOfA from B b);
到目前为止我能做到的是
public List<A> getANotInB() {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// Select From Table B
CriteriaQuery<B> criteriaQueryB = criteriaBuilder
.createQuery(B.class);
Root<B> rootB = criteriaQueryB.from(B.class);
criteriaQueryB.select(rootB);
// Select records from Table A
CriteriaQuery<A> criteriaQueryA = criteriaBuilder.createQuery(A.class);
Root<A> rootA = criteriaQueryA.from(A.class);
criteriaQueryA.select(A);
// Create predicate
Predicate predicate = rootAttemptA.in(criteriaQueryB.getSelection());
criteriaQueryA.where(criteriaBuilder.not(predicate));
// Create query
TypedQuery<A> query = entityManager.createQuery(criteriaQueryA);
List<A> as= query.getResultList();
System.out.println(as);
return as;
}
我知道上面的代码不正确,我有很多基础wong。
请帮助
注意:我想使用 JPA2 Criteria Query
试试这个
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
// Select distinct aid from B
CriteriaQuery<B> bQuery = cb.createQuery(B.class);
Root<B> bRoot = bQuery.from(B.class);
bQuery.select(bRoot.get("a").get("id")).distinct(true);
// Select * from A where aid not in ()
CriteriaQuery<A> aQuery = cb.createQuery(A.class);
Root<A> aRoot = aQuery.from(A.class);
aQuery.select(aRoot).where(cb.not(aRoot.get("id").in(bQuery)));
TypedQuery<A> query = entityManager.createQuery(aQuery);
List<A> result = query.getResultList();
基本上,您将构造部分查询并将它们粘合在一起。
更多信息在这里:
我能够使用 subquery() 完成它,如下所示。发布它以便它可以帮助其他人
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// select a from A a
CriteriaQuery<A> queryA = criteriaBuilder.createQuery(A.class);
Root<A> rootA = queryA.from(A.class);
queryA.select(rootA);
// Select distinct aId from B
CriteriaQuery<B> subQueryB = queryA.subquery(B.class);
Root<B> rootB = subQueryB.from(B.class);
bQuery.select(rootB.get("a")).distinct(true);
queryA.where(criteriaBuilder.not(criteriaBuilder.in(rootA.get("id").value(subQueryB))));
TypedQuery<A> query = entityManager.createQuery(aQuery);
List<A> result = query.getResultList();
感谢@Mạnh 指路
我有以下table结构如下
Table A {
id <-- Primary key
someColumn
}
Table B {
id <-- Primary key
someColumn
idOfA <-- Foreign key mapping to Table A
}
实体类如下所示
@Entity
@Table(name = "A")
public class A implements Serializable {
private static final long serialVersionUID = -78448557049178402L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
.......
.......
@OneToMany(mappedBy = "a")
private List<B> bs = new ArrayList<>();
}
@Entity
@Table(name = "B")
public class B implements Serializable {
private static final long serialVersionUID = -659500557015441771L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
.......
.......
@OneToOne
@JoinColumn(name = "a_id", nullable = false)
private A a;
}
使用 JPA2,我想 select 来自 table A 的记录在 Table B 中没有引用
预期的本机 postgres 查询是
select * from A a
where a.id not in
(select b.idOfA from B b);
到目前为止我能做到的是
public List<A> getANotInB() {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// Select From Table B
CriteriaQuery<B> criteriaQueryB = criteriaBuilder
.createQuery(B.class);
Root<B> rootB = criteriaQueryB.from(B.class);
criteriaQueryB.select(rootB);
// Select records from Table A
CriteriaQuery<A> criteriaQueryA = criteriaBuilder.createQuery(A.class);
Root<A> rootA = criteriaQueryA.from(A.class);
criteriaQueryA.select(A);
// Create predicate
Predicate predicate = rootAttemptA.in(criteriaQueryB.getSelection());
criteriaQueryA.where(criteriaBuilder.not(predicate));
// Create query
TypedQuery<A> query = entityManager.createQuery(criteriaQueryA);
List<A> as= query.getResultList();
System.out.println(as);
return as;
}
我知道上面的代码不正确,我有很多基础wong。 请帮助
注意:我想使用 JPA2 Criteria Query
试试这个
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
// Select distinct aid from B
CriteriaQuery<B> bQuery = cb.createQuery(B.class);
Root<B> bRoot = bQuery.from(B.class);
bQuery.select(bRoot.get("a").get("id")).distinct(true);
// Select * from A where aid not in ()
CriteriaQuery<A> aQuery = cb.createQuery(A.class);
Root<A> aRoot = aQuery.from(A.class);
aQuery.select(aRoot).where(cb.not(aRoot.get("id").in(bQuery)));
TypedQuery<A> query = entityManager.createQuery(aQuery);
List<A> result = query.getResultList();
基本上,您将构造部分查询并将它们粘合在一起。
更多信息在这里:
我能够使用 subquery() 完成它,如下所示。发布它以便它可以帮助其他人
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// select a from A a
CriteriaQuery<A> queryA = criteriaBuilder.createQuery(A.class);
Root<A> rootA = queryA.from(A.class);
queryA.select(rootA);
// Select distinct aId from B
CriteriaQuery<B> subQueryB = queryA.subquery(B.class);
Root<B> rootB = subQueryB.from(B.class);
bQuery.select(rootB.get("a")).distinct(true);
queryA.where(criteriaBuilder.not(criteriaBuilder.in(rootA.get("id").value(subQueryB))));
TypedQuery<A> query = entityManager.createQuery(aQuery);
List<A> result = query.getResultList();
感谢@Mạnh 指路