【问题标题】:JPQL query by foreign keyJPQL 外键查询
【发布时间】:2021-04-06 00:44:40
【问题描述】:

有两个表 PersonEntity 和 cityentity。数据库中的 PersonEntity 通过外部键 fk_cityid 链接到 cityentity。我需要选择具有给定 CityId 的 PersonEntity 表的所有记录(名称)。 Join 无处不在,但在这种情况下,我不需要来自 cityentity 表的数据,只需要 PersonEntity 表的 name 字段。以下是类的描述:

@Entity
public class PersonEntity {
    private Long id;
    private String name;
    private CityEntity cityId;
}
@Entity
public class CityEntity {
    private Long id;
    private String name;
}

这是 HQL 查询:

@Repository
public interface PersonEntityRepository extends JpaRepository<PersonEntity, Long> {
  @Query("select p.name FROM PersonEntity p where (p.name = :name or :name is null) " +
        "and (p.cityId = :cityId or :cityId is null)")
    List<PersonEntity> findByNameAndCity (
        @Param("name") String name,
        @Param("cityId") CityEntity cityId);
}

通过 id 尝试过:

@Query("select p.name FROM PersonEntity p where (p.name = :name or :name is null) " +
        "and (p.cityId.id = :cityId or :cityId is null)")
    List<PersonEntity> findByNameAndCity (
        @Param("name") String name,
        @Param("cityId") Long cityId);

在这两种情况下,错误都是:“无法确定数据类型”。

调用函数的选项:

servisPerson.findByNameAndCity (null, cityId);

servisPerson.findByNameAndCity (name, null);

其实不止两个参数。为了简化,我只展示了两个。

servisPerson.findByNameAndCity (name, age, ..., cityId);

【问题讨论】:

    标签: java spring spring-boot spring-data-jpa jpql


    【解决方案1】:

    Person 实体应该看起来像这样

    @Entity
    public class PersonEntity {
         private Long id;
         private String name;
    
         @OneToOne
         @JoinColumn(name = "city_id")
         private CityEntity city;
    }
    

    你可以这样写你的查询

    List<PersonEntity> findByNameAndCityOrNameIsNullOrCityIsNull(String name, CityEntity city);
    

    Spring Data JPA 非常聪明,可以在后台为您生成查询。

    顺便说一句,您尝试写的是JPQL,而不是HQL

    编辑(对长方法名称的评论的反应):

    我建议避免创建 JPQL 查询,因为这样更容易出错。如果您不喜欢冗长的方法名称,可以将其包装成存储库中较短的默认方法:

    @Repository
    public interface PersonEntityRepository extends  JpaRepository<PersonEntity, Long> {
         List<PersonEntity> findByNameAndCityOrNameIsNullOrCityIsNull(String name, CityEntity city);
         
         default List<PersonEntity> shortName(String name, CityEntity city) {
             return findByNameAndCityOrNameIsNullOrCityIsNull(name, city);
         }
    }
    

    【讨论】:

    • 是的,它就是这样工作的。但事实是任何字段都可以为 = null。然后这样的请求会导致错误。为此,我在 HQL 中添加了“或:名称为零”。如何在 Spring Data JPA 中编写我不知道。findByNameOrIsNullAndCityOrIsNull ???不确定这是否正确
    • 对,对不起,我错过了关于空值的文章。最初只关注 PersonEntity 中的链接问题。答案已更新。
    • 谢谢。但是如何在 HQL 上做到这一点?因为在 JPQL 上,函数名称会太大。 findByNameAndCityAndAggAnd.....OrNameIsNullOrCityIsNullOrAggIsNullOr.....
    • @Alex,编辑了我的答案以反映此评论。
    • 这样不行。函数 findByNameAndCityOrNameIsNullOrCityIsNull 总是返回一个空列表。 findByNameAndCityOrNameIsNullOrCityIsNull ("name", "city") - 这就是它的工作原理。所以 findByNameAndCityOrNameIsNullOrCityIsNull("name", null) 返回一个空列表
    猜你喜欢
    • 2015-07-15
    • 1970-01-01
    • 2012-07-11
    • 2017-03-10
    • 2013-11-13
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多