java 具有多个连接的 JPA 条件构建器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3870944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA criteria builder with multiple joins
提问by
i'm struggling to create a jpa query that makes use of several tables. i cannot seem to understand how to join the tables together. this is the query i am trying to create:
我正在努力创建一个使用多个表的 jpa 查询。我似乎无法理解如何将表连接在一起。这是我试图创建的查询:
SELECT algm.m_l_i, algnsm.n_s_i
FROM algm, alg, algnsm, mal
WHERE algm.l_g_i = alg.l_g_i
AND alg.l_g_t = 'xxx'
AND algnsm.l_g_i = algm.l_g_i
AND mal.c_l_i = algm.m_l_i
AND mal.p_l_i = 'yyy';
i have tried several approaches, from using the join operator to using the where operator on the keys. i cannot find enough info on joins on the net to help much. i get stuck as soon as i try to join more than 1 table deep. some advice or tips would really be useful. thanks
我尝试了几种方法,从使用 join 运算符到在键上使用 where 运算符。我在网上找不到足够的关于加入的信息来帮助很多。一旦我尝试加入超过 1 个表的深度,我就会陷入困境。一些建议或技巧真的很有用。谢谢
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = builder.createTupleQuery();
Root<MAL> malRoot = query.from(MAL.class);
Root<ALGM> algmRoot = query.from(ALGM.class);
// error
algmRoot.join(ML_.mLI);
// error
malRoot.join(ML_.mLI);
Predicate e1 = builder.equal(malRoot.get(MAL_.pL).get(ML_.mLI), "abc");
Predicate e2 = builder.equal(malRoot.get(MAL_.cL), algmRoot.get(ALGM_.mL));
query.where(builder.and(e1, e2));
query.select(builder.tuple(malRoot.get(MAL_.pL), malRoot.get(MAL_.cL), algmRoot.get(ALGM_.aLG).get(ALG_.lGT)));
@Entity
@Table(name = "M_A_L")
public class MAL implements Serializable {
@EmbeddedId
protected MALPK malPK;
@Basic(optional = false)
@Column(name = "ENTRY_IND")
private String entryInd;
@JoinColumn(name = "P_L_I", referencedColumnName = "M_L_I", insertable = false, updatable = false)
@ManyToOne(optional = false)
private ML pL;
@JoinColumn(name = "C_L_I", referencedColumnName = "M_L_I", insertable = false, updatable = false)
@ManyToOne(optional = false)
private ML cL;
...
}
@Entity
@Table(name = "A_L_G_M")
public class ALGM implements Serializable {
@EmbeddedId
protected ALGMPK algmPK;
@JoinColumn(name = "M_L_I", referencedColumnName = "M_L_I", insertable = false, updatable = false)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ML mL;
@JoinColumn(name = "L_G_I", referencedColumnName = "L_G_I", insertable = false, updatable = false)
@ManyToOne(optional = false)
private ALG aLG;
....
}
public class ALGM_ {
public static volatile SingularAttribute<ALGM, ML> mL;
public static volatile SingularAttribute<ALGM, ALGMPK> aLGMPK;
public static volatile SingularAttribute<ALGM, ALG> aLG;
}
public class MAL_ {
public static volatile SingularAttribute<MAL, String> eI;
public static volatile SingularAttribute<MAL, MALPK> mALPK;
public static volatile SingularAttribute<MAL, ML> pL;
public static volatile SingularAttribute<MAL, ML> cL;
}
public class ALG_ {
public static volatile CollectionAttribute<ALG, MW> mWC;
public static volatile SingularAttribute<ALG, ALGCM> aLGCM;
public static volatile SingularAttribute<ALG, ALGAVM> aLGAVM;
public static volatile SingularAttribute<ALG, TR> tZ;
public static volatile CollectionAttribute<ALG, ALGM> aLGMC;
public static volatile SingularAttribute<ALG, String> d;
public static volatile SingularAttribute<ALG, String> lGT;
public static volatile SingularAttribute<ALG, String> lGI;
public static volatile SingularAttribute<ALG, ALGNSM> aLGNSM;
public static volatile SingularAttribute<ALG, ALGFVM> aLGFVM;
public static volatile SingularAttribute<ALG, ALGNAM> aLGNAM;
}
回答by ShayM
Joins in JPA query go like this :
JPA 查询中的连接如下所示:
to create a join from A to B:
创建从 A 到 B 的连接:
Root<A> root ....
CriteriaQuery<?> query .....
CriteriaBuilder builder.....
Join<A, B> BTable = root.join(SingularAttribute<A, B>);
or
或者
Join<A, B> BTable = root.join(A_.B);
once you have the ref to bTable you can use it for path variables.
一旦你有了 bTable 的引用,你就可以将它用于路径变量。