过滤表中的数据-如何正确组织它

6yt4nkrj  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(262)

我研究spring+hibernate捆绑包有一个实体:

public class PersonEntity {
    private Long id;
    private String name;
    private Integer age;
    private City city;
    private Countrycountry;
...
}

我需要进行过滤。此表中的数据将显示在浏览器窗口中。我正在考虑实现以下方法:

.findByName(name);
.findByNameAndAge(name, age);
.findByNameAndAge(name, age, city);
.findByNameAndAge(name, city);
...

但事实证明,方法的选择太多了。如何创建一个通用方法,例如,可以根据需要添加任意多个参数的集合。我开始读关于这个问题的书,完全搞糊涂了。在他们写@filter的地方,在hibernate搜索的地方,还有spring数据ElasticSearch。告诉我最简单和最相关的方法来实现这一点。如果有链接到真实的例子,我将非常感谢。
道:

public interface PersonDao extends GeneralDAO<PersonEntity>{
    public List<PersonEntity> searchName(String name);
    public List<PersonEntity> searchAllFields(
            String name,
            Integer age,
            City city);
}

generaldao描述了所有标准方法,如get、save等。存储库:

@Repository
public interface PersonRepository extends JpaRepository<PersonEntity, Long> {
    List<PersonEntity> findByNameIgnoreCase(String name);
    List<PersonEntity> findByNameAndAgeAndCity(
            String name,
            Integer age,
            City city);
}

服务

@Service
@Transactional
public class PersonService implements PersonRepository {
    @Autowired
    private PersonRepository personRepository;

    ...
    описание всех стандартных методов чтения-записи в БД

    @Override
    public List<PersonEntity> searchName(String name) {
        return productTypeRepository.findByNameIgnoreCase(name);
    }

    @Override
    public List<PersonEntity> searchAllFields(
            String name,
            Integer age,
            City city) {
        return personRepository.findByNameAndAgeAndCity(
                name,
                age,
                city);
    }
}

在ad和呼叫控制器中:

@Autowired
private PersonService personService;
...

personService.searchAllFields(...);

searchname方法可以正常工作,但searchallfields不行。它总是返回一个空列表,即使我指定了一个名称,其余的都是null
我尝试更改服务中的方法:

List<PersonEntity> findByNameIsNullAndAgeIsNullAndCityIsNull

spring返回一个错误:“创建名为personrepository的bean时出错。至少提供了1个参数,但查询中仅存在0个参数”。

svdrlsy4

svdrlsy41#

searchallfields方法正在返回一个空列表,因为它包含findBynameandgeAndCity,这意味着所有参数都是必需的,并且它们之间的条件是,因此最好更改为or(findbynameorageorcity),这样,如果您传递一个值,如name和rest=null,那么您也将获得数据,反之亦然。

rjee0c15

rjee0c152#

你真的应该考虑使用 Criteria API 既然你用的是 Spring & Spring Data ,您可以使用jpa规范作为完整的示例,请参见以下示例:

import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
....
public interface PersonRepository extends JpaRepository<PersonEntity, Long>, JpaSpecificationExecutor {
}

//请注意第二个扩展接口jpaspecificationexecutor^
使用中:

import org.springframework.data.jpa.domain.Specification;
....

public List<PersonEntity> list(PersonEntityFilter personFilter) {
    List<PersonEntity> filteredPersons = personsRepository.findAll
        (Specification.where(PersonEntitySpecs.findByFilters(personFilter)));
    return filteredPersons;
  }
``` `PersonEntityFilter` 负载是否来自客户端或用户界面提交的控制器,并且它是一个简单的类,对所有要按其进行筛选的字段进行分组

public class PersonEntityFilter {
private String name;
private Integer age;
private City city;

 // getters & setters

}
``` PersonEntitySpecs 是放置规范的地方(条件查询逻辑)

public class PersonEntitySpecs {

 public static Specification<PersonEntity> findByFilters(PersonEntityFilter personEntityFilter) {
    return (root, query, cb) -> {
      final Collection<Predicate> predicates = new ArrayList<>();
      if (personEntityFilter.getName() != null) {
        predicates.add(cb.like(root.get("name"), "%" + personEntityFilter.getName() + "%")));
      }

      if (personEntityFilter.getAge() != null) {
        predicates.add(cb.equal(root.get("age"), personEntityFilter.getAge()));
      }

      if (personEntityFilter.getCity() != null) {
        Join<PersonEntity, CityEntity> personCityJoin = root.join("city");

        predicates.add(cb.equal(personCityJoin.get("id"), personEntityFilter.getCity().getId()));
      }

      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
   }
}

相关问题