将 SQL Left Join 查询翻译成 EclipseLink JPA 查询
Translate SQL Left Join query to EclipseLink JPA query
我正在尝试编写 JPA NamedQuery。我有一个有效的 SQL 查询如下:
SELECT MIN(t1.Id + 1) AS nextID
FROM
MyTable t1 LEFT JOIN MyTable t2
ON
t1.Id + 1 = t2.Id
WHERE
t2.Id IS NULL
我无法将此查询转换为 JPQL 语法。
我认为使用标准 JPQL 无法进行此类自定义联接。前段时间我一直在寻找这样做的可能性,发现 Hibernate 提供了一个专有扩展 @JoinFormula
来实现这一点,参见。 Hibernate @JoinFormula。但是我找不到 EclipseLink 的等效项。
您可以使用 @NamedNativeQuery
和 @SqlResultSetMapping
将您的 SQL 语句映射到 JPA 实体,如下所示:
@NamedNativeQuery( name = "customJoin",
query = "SELECT MIN(t1.Id + 1) AS nextID FROM MyTable t1 LEFT JOIN MyTable t2 ON t1.Id + 1 = t2.Id WHERE t2.Id IS NULL",
resultSetMapping = "customJoinMapping" )
@SqlResultSetMapping( name = "customJoinMapping",
entities = @EntityResult( entityClass = MyTable.class, fields = @FieldResult( name = "id", column = "nextID" ) ) )
@Entity
@Access( AccessType.Field )
public class MyTable {
private int id;
public int getId() {
return this.id;
}
public void setId( int id ) {
this.id = id;
}
}
更新
很久以后,我找到了一种在 EclipseLink 中自定义关系连接的方法 here。要使用的功能是 DescriptorCustomizer
,可以将其放置在具有 @Customizer
.
的 JPA 实体上
在 customize()
方法中,可以使用 EclipseLink 表达式 API 表达额外的连接条件。例如,以下代码片段将生成附加连接条件 [...] AND TargetEntity.someAttribute IN ('V', 'W', 'U')
(其中 someRelationship
指向 TargetEntity
)。
OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName( "someRelationship" );
Expression origExp = mapping.buildSelectionCriteria();
ExpressionBuilder expBuilder = origExp.getBuilder();
Expression constantExp = expBuilder.get( "someAttribute" ).in( new String[] { "V", "W", "U" } );
Expression newExp = origExp.and( constantExp );
mapping.setSelectionCriteria( newExp );
我正在尝试编写 JPA NamedQuery。我有一个有效的 SQL 查询如下:
SELECT MIN(t1.Id + 1) AS nextID
FROM
MyTable t1 LEFT JOIN MyTable t2
ON
t1.Id + 1 = t2.Id
WHERE
t2.Id IS NULL
我无法将此查询转换为 JPQL 语法。
我认为使用标准 JPQL 无法进行此类自定义联接。前段时间我一直在寻找这样做的可能性,发现 Hibernate 提供了一个专有扩展 @JoinFormula
来实现这一点,参见。 Hibernate @JoinFormula。但是我找不到 EclipseLink 的等效项。
您可以使用 @NamedNativeQuery
和 @SqlResultSetMapping
将您的 SQL 语句映射到 JPA 实体,如下所示:
@NamedNativeQuery( name = "customJoin",
query = "SELECT MIN(t1.Id + 1) AS nextID FROM MyTable t1 LEFT JOIN MyTable t2 ON t1.Id + 1 = t2.Id WHERE t2.Id IS NULL",
resultSetMapping = "customJoinMapping" )
@SqlResultSetMapping( name = "customJoinMapping",
entities = @EntityResult( entityClass = MyTable.class, fields = @FieldResult( name = "id", column = "nextID" ) ) )
@Entity
@Access( AccessType.Field )
public class MyTable {
private int id;
public int getId() {
return this.id;
}
public void setId( int id ) {
this.id = id;
}
}
更新
很久以后,我找到了一种在 EclipseLink 中自定义关系连接的方法 here。要使用的功能是 DescriptorCustomizer
,可以将其放置在具有 @Customizer
.
在 customize()
方法中,可以使用 EclipseLink 表达式 API 表达额外的连接条件。例如,以下代码片段将生成附加连接条件 [...] AND TargetEntity.someAttribute IN ('V', 'W', 'U')
(其中 someRelationship
指向 TargetEntity
)。
OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName( "someRelationship" );
Expression origExp = mapping.buildSelectionCriteria();
ExpressionBuilder expBuilder = origExp.getBuilder();
Expression constantExp = expBuilder.get( "someAttribute" ).in( new String[] { "V", "W", "U" } );
Expression newExp = origExp.and( constantExp );
mapping.setSelectionCriteria( newExp );