java - 如何制作具有以下签名 '(x OR y) AND z'的spring data自定义查询方法

标签 java spring jpa spring-data

我有以下存储库,其中包含 2 种自定义查询方法:

@Repository
public interface CropVarietyNameDao extends JpaRepository<CropVarietyName, Long> {
    //https://stackoverflow.com/questions/25362540/like-query-in-spring-jparepository
    Set<CropVarietyName> findAllByNameIgnoreCaseContainingOrScientificNameIgnoreCaseContaining(String varietyName, String scientificName);
    Set<CropVarietyName> findAllByNameIgnoreCaseStartsWithOrScientificNameIgnoreCaseStartsWith(String varietyName, String scientificName);
}

我需要添加一个附加条件,即父实体名为crop returned = false

如果我将方法更改为以下内容:

findAllByNameIgnoreCaseContainingOrScientificNameIgnoreCaseContainingAndCrop_deletedIsFalse(字符串品种名称,字符串科学名称);

那么它很可能会将查询解释为(名称包含 OR (scientificNameContaining AND Crop_deleted = false),但这不是我想要的。 它需要是(NameContaining OR ScientificNameContaining) AND Crop_deleted = false)

我的猜测是我必须将 AND Crop_deleted 部分添加到这两个部分,但这似乎效率低下。我如何编写一个基本上是 (NameContaining OR ScientificNameContaining) AND Crop_deleted = false) 的方法,而不必使用 @Query

最佳答案

您可以尝试 JPA 规范 -

@Repository
public interface CropVarietyNameDao extends JpaRepository<CropVarietyName, Long>,
        JpaSpecificationExecutor<CropVarietyName> {
}

public class CropVarietySpecs {

        public static Specification<CropVarietyName> cropPredicate(String varietyName, String sciName, boolean cropStatus) {
        return new Specification<CropVarietyName>() {
            @Override
            public Predicate toPredicate(Root<CropVarietyName> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                Predicate varietyContainingIgnoreCasePredicate = criteriaBuilder.like(criteriaBuilder.lower(root.get("<column_name>")), varietyName.toLowerCase());
                Predicate scientificContainingIgnoreCasePredicate = criteriaBuilder.like(criteriaBuilder.lower(root.get("<column_name>")), sciName.toLowerCase());
                Predicate cropStatusPredicate = criteriaBuilder.equal(root.get("<column_name>"), cropStatus);
                predicates.add(varietyContainingIgnoreCasePredicate);
                predicates.add(scientificContainingIgnoreCasePredicate);
                criteriaBuilder.or(predicates.toArray(new Predicate[predicates.size()]));
                return criteriaBuilder.and(cropStatusPredicate);
            }
        };

    }
}

然后你可以调用存储库的 findAll() 方法,例如 -

List<CropVarietyName> entities = cropVarietyNameDao.findAll(CropVarietySpecs.cropPredicate("varietyName", "sciName", false));

关于java - 如何制作具有以下签名 '(x OR y) AND z'的spring data自定义查询方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59547704/

相关文章:

java - LinkedList subList 返回 List 而不是 LinkedList?

java - 我应该用一个字段创建 Spring 模型类吗?

java - @Scheduled 使用 spring 4 java 配置运行两次

java - Spring Hibernate查询与非主键的一对一关系

java - JPA 在创建后返回嵌套对象 - 500 内部服务器错误

java - 从 docker 启动 HSQL 服务器时运行默认脚本

java - 我正在尝试生成一个随机 #,转换为字符串,然后根据转换后的字符串分配花色

java - EclipseLink DDL 生成错误

java - 即使 onDestroy 被触发,我的服务也不会停止

java - 使用 Spring-MVC 降低 Java Web 应用程序中的部署频率