访问多个表

时间:2012-08-18 12:51:44

标签: java jpa-2.0 eclipselink ejb-3.1

我正在学习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语句。

1 个答案:

答案 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与此无关,当单个实体被拆分为多个表时,将使用它。