当前位置: 首页 > 知识库问答 >
问题:

如何使用querydsl或spring数据jpa规范对分层实体执行查询?

毛成济
2023-03-14

我有一个这样的实体层次结构。除了一些常见属性外,一些属性仅由少数子类型共享:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
    private String firstName;
    private String lastName

    ... further properties, getters and setters...
}

@Entity
public class Employee extends Person {
    private String salary;

    ... further properties, getters and setters...
}

@Entity
public class BoardMember extends Person {
    private String salary;

    ... further properties, getters and setters...
}

@Entity
public class ExternalMember extends Person {
    private String clearanceLevel;

    ... further properties, getters and setters...
}

@Repository
public interface PersonRepository extends JpaRepository<Person, Long>, QuerydslPredicateExecutor<Person> {

}

使用QueryDSL,我试图根据动态筛选标准搜索人员,如:

@Service
@Transactional
public class PersonService {

  @Autowired
  PersonRepository personRepository;

  public Page<Person> search(String firstName, String salary) {
    var searchCriterias = new BooleanBuilder();
    if (firstName != null) {
      searchCriterias.and(QPerson.firstName.eq(firstName));
    }
    if (salary != null) {
        searchCriterias.andAnyOf(
          QPerson.person.as(QEmployee.class).salary.eq(salary),
          QPerson.person.as(QBoardMember.class).salary.eq(salary),
        );
    }
    personRepository.findAll(searchCriterias);
  }
}

这似乎不是正确的方式,然而,我得到了很多错误,比如“薪水”不是一个人的成员。

处理层次实体搜索的各种方法有哪些?为了类型安全,我更喜欢QueryDSL,但使用Spring数据规范的解决方案也可以。

编辑:使用15种不同的搜索标准,搜索标准可能会变得非常复杂。所以我需要一个程序化的方法来制定它们。

共有1个答案

养振濂
2023-03-14

我无法重现“不是个人成员”错误,但我设法从您的查询中获得了结果。

根据Baeldung的教程,并根据您的问题修改代码,我成功地获得了无误的结果。以下是示例项目。希望这有帮助

import javax.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column
    private String firstName;

    @Column
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Person() {
    }
}
import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class BoardMember extends Person {

    @Column
    private String salary;

    public BoardMember(String firstName, String lastName, String salary) {
        super(firstName, lastName);
        this.salary = salary;
    }

    public BoardMember() {
    }
}
@Service
@Transactional
public class PersonService {

    @Autowired
    PersonRepository personRepository;

    public List<Person> search(String firstName, String salary) {
        var searchCriterias = new BooleanBuilder();
        if (firstName != null) {
            searchCriterias.and(QPerson.person.firstName.eq(firstName));
        }
        if (salary != null) {
            searchCriterias.andAnyOf(
                    QPerson.person.as(QEmployee.class).salary.eq(salary),
                    QPerson.person.as(QBoardMember.class).salary.eq(salary)
            );
        }

        var result = new ArrayList<Person>();
        for (Person person : personRepository.findAll(searchCriterias)) {
            result.add(person);
        }
        return result;
    }
}
 类似资料:
  • QueryDSL定义了一个接口,通过调用或可以轻松地为任何字段获取该接口的实例。Spring Data JPA的接口甚至有一个方法,它将作为参数。 但是对QueryDSL一无所知,它有自己定义查询排序顺序的方法,即。它可以包含许多,它们与非常相似,只是它们不是类型安全的。 所以,如果我想做使用排序的分页查询,真的没有办法使用QueryDSL来定义它吗?

  • 我按照本教程获得了Spring Data JPA规范:https://dzone.com/articles/using-spring-data-jpa-specification 它为我实现了这一点,但我不能调用规范方法来搜索它们。我想把它们放在我的SearchController中: 现在我想在我的SearchController(比如Controller)中调用这个方法,但我不知道如何调用。目

  • 我正在尝试使用Querydsl(4.1.4)查询JPA,如本文http://www.Querydsl.com/static/Querydsl/latest/reference/html/ch02.html#jpa_integration所述。我使用Hibernate(5.2.12.final)作为JPA后端。我使用和处理器从JPA注释类生成Querydsl查询类型。 这将打印: 原始JpaUpda

  • 我不能同时使用Spring Data,JPA投影和规范。我有以下设置: 实体: 投影界面: 国家规格: 存储库: 前两个方法findByName和findAllProjectedBy工作良好。而第三个方法findAllProjectedBy(Specification Specification)抛出以下异常- 如何才能做到这一点呢?有什么想法吗?

  • 我正在使用一个JPA查询,它使用一个规范来检索实体。当我执行查询时,我得到了一个错误: 组织。springframework。数据映射。PropertyReferenceException:找不到类型任务的属性名称! 我已经查看了之前在该网站上提出的类似问题的答案 当我使用调试器逐步检查代码时,条件生成器中的扩展路径将返回嵌入的ID类,但当规范实际用于查询时,该属性似乎正在应用于基本实体类。 我是

  • 我正在回答这个问题,在单个表的日期、整数和字符串数据类型字段上执行多列搜索?并且该方法必须返回Java 8中类型specification 的结果。 实际上,我想在关联实体中搜索,以及全局搜索的一部分。使用是否可能? 我有和@onetomany关系。 EmployeeController.java java 当我点击时,我希望在表和表中进行搜索(可能使用类似)。这可能吗?如果是,我们怎么做? 有什