我正在学习EJB,JPA并且有非常基本的怀疑
我有3张表A,B,C
A - ID,姓名
B - ID,姓名
C - ID,A_ID,B_ID
当我从数据库创建实体类时,我得到3个带有JPA东西的EJB类。
现在在我的Managed bean中,我得到A.Name或B.Name,我需要使用C找到匹配的条目。
普通SQL查询看起来像(可能不是最好的查询)
SELECT a.name FROM schema.A a,schema.B b,schema.C c其中b.Name ='ABC',c.B_ID = b.ID,a.ID = c.A_ID;
现在我在哪里进行上述查询。
我遇到了@SecondaryTable,但无法理解它的使用方式。
我还看到了em.createQuery(SQL查询).getResultList()。
现在是上面最好的方法,或者EJB / JPA中哪些东西更好。
更新1:
我试图在em.CreateQuery
中执行查询em.CreateQuery(SELECT a.name FROM A a,B b,C c,其中b.Name ='ABC',c.B_ID = b.ID,a.ID = c.A_ID).getResultList();
但是我的GlassFish服务器出现了以下错误(我正在使用EclipeLink JPA)
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
Position:
Error Code: 0
Call: SELECT t0.given_name FROM test.a t3, test.a_b t2, test.b t1, test.a t0 WHERE ((((t1.Name = ?) AND (t2.b_id = t1.id.t1.id)) AND (t0.id = )) AND (t3.id = t2.a_id))
bind => [1 parameter bound]
Query: ReportQuery(referenceClass=Consultant sql="SELECT t0.given_name FROM test.a t3, test.a_b t2, test.b t1, test.a t0 WHERE ((((t1.Name = ?) AND (t2.b_id = t1.id.t1.id)) AND (t0.id = )) AND (t3.id = t2.a_id))")
现在为什么SQl语句在错误日志
中搞砸了1.有一个额外的入门测试.a t0
2.t2.b_id = t1.id.t1.id
3.t0.id =
如何生成错误日志SQL语句。
答案 0 :(得分:1)
由于C是A和B之间的多对多关系,因此它不应该是一个实体。但是,我不认为JPA喜欢你的连接表(C)拥有它自己的ID列。如果可能,从C中删除ID列,并将A_ID,B_ID组合为主键。
然后实体类A可以:
@JoinTable(name = "C",
joinColumns = { @JoinColumn(name = "A_ID", referencedColumnName = "ID") },
inverseJoinColumns = { @JoinColumn(name = "B_ID", referencedColumnName = "ID") })
@ManyToMany
private Collection<B> bCollection;
我认为所有这些注释的含义都很清楚。 B级会有:
@ManyToMany(mappedBy = "bCollection")
private Collection<A> aCollection;
mappedBy属性告诉JPA使用A :: bCollection的JoinTable防御(A是从字段的类型Collection&lt; A&gt;中推断出来的。)
现在,如果您有A的实例,您可以通过获取该属性轻松获得该A的所有B。不需要任何SQL / JPQL。
现在,对于执行查询,您应该知道您拥有JPQL和SQL。 JPQL是Java持久性查询语言,是JPA的语言。 SQL是数据库的本机语言。要执行SQL,您需要使用createNativeQuery系列函数。 createQuery函数适用于JPQL。
您应该更喜欢JPQL而不是SQL。两者之间最重要的区别是JPQL适用于您的实体,并期望所有标识符对应于您的类和属性使用的名称。例如,如果Name列(首字母大写)映射到名为name(小写)的属性,那么在JPQL查询中,您应该使用name(小写)。实体类名称和相应的表名称相同。 JPQL还建立了对多对多关系的连接表的支持,以及你想要的JPQL查询
SELECT a
FROM B b JOIN b.aCollection a
WHERE b.name='ABC'
无需指定JPA从类的注释中了解所有连接条件。
@SecondaryTable与此无关,当单个实体被拆分为多个表时,将使用它。