代码之家  ›  专栏  ›  技术社区  ›  htshame

JPA搜索字符串,长和布尔值

  •  1
  • htshame  · 技术社区  · 7 年前

    我有一个Spring Boot应用程序。有一个实体:

    @Entity
    @Table(name = "user")
    public class User {
        private Long id;
        private String name;
        private Long schoolId;
        private Boolean isActive;
        // getters and setters
    }
    

    我有一个仓库:

    @Repository
    public interface UserRepositoryPageable extends PagingAndSortingRepository<User, Long> {
    }
    

    我需要请求搜索 schoolId 和过滤器 所有字段 一根绳子。

    像这样的:

    @Query("SELECT u FROM User u " +
            "WHERE u.schoolId = :schoolId AND (" +
            "u.id like %:searchVal% OR " +
            "u.name like %:searchVal% OR " +
            "u.isActive like %:searchVal%)")
    Page<User> getUserBySchoolIdWithFilter(@Param("schoolId") Long schoolId,
                                           Pageable pageable,
                                           @Param("searchVal") String searchVal);
    

    但我收到一个例外因为我想申请 like Long Boolean 是的。

    例如 ,如果尝试按“testsearchvalue”筛选,则会收到以下异常:

    java.lang.IllegalargumentException:参数值[%TestSearchValue%]与预期的类型[java.lang.Long]不匹配(N/A)

    不幸的是, CAST CONVERT 没有为我工作过。

    有什么解决办法吗?

    一些细节

    我派了一个 GET 对此API的请求:

    @RequestMapping(path = "users/{schoolId}/search", method = GET)
    public ResponseEntity<Page<User>> searchUserBySchoolWithFilter(
                        @PathVariable(value = "schoolId") Long schoolId, Pageable pageable,
                        @RequestParam(value = "searchVal", required = false) String searchVal) {
        return new ResponseEntity<>(userService
                    .getUserBySchoolIdWithFilter(schoolId, pageable, searchVal), HttpStatus.OK);
        }
    

    然后进入 UserService 以下内容:

    public Page<User> getUserBySchoolIdWithFilter(Long schoolId, Pageable pageable, String searchVal) {
        return userRepositoryPageable.getUserBySchoolIdWithFilter(schoolId, pageable, searchVal);
    }
    

    所以:

    在我看来,这个问题的基本要点是 布尔型 作为 String 是的。
    也许用它更好 nativeQuery 是吗?如果是的话,那么你能给我一个关于如何使用的提示吗 CAST() CONVERT() 具有 LIKE 条款?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Dimitar Spasovski    7 年前

    你考虑过 Specifications 是吗?

    使用规范,可以动态生成 WHERE spring数据查询的一部分。 为了在spring数据jpa查询中使用规范,必须扩展 org.springframework.data.jpa.repository.JpaSpecificationExecutor 接口。因此,您的用户存储库可以如下所示:

    public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
    }
    

    你的搜索方法可能是这样的

    public List<User> getAllFilterByString(String text) {
    
        if(StringUtils.isEmpty(text))
            return userRepository.findAll();
    
        Specification<User> specification =
                (root, query, cb) -> {
                    List<Predicate> predicates = new ArrayList<>();
                    predicates.add(cb.like(cb.lower(root.get("name")), "%"+text.toLowerCase()+"%"));
    
                    //check if the text value can be casted to long.
                    //if it is possible, then add the check to the query
                    try {
                        long longValue = Long.valueOf(text);
                        predicates.add(cb.equal(root.get("id"), longValue));
                    }
                    catch (NumberFormatException e) {
                        //do nothing, the text is not long
                    }
    
                    //check if the text can be casted to boolean
                    //if it is possible, then add the check to the query
    
                    Boolean value = "true".equalsIgnoreCase(text) ? Boolean.TRUE :
                            "false".equalsIgnoreCase(text) ? Boolean.FALSE : null;
    
                    if(value != null) {
                        predicates.add(cb.equal(root.get("isActive"), value));
                    }
    
                    return cb.or(predicates.toArray(new Predicate[] {}));
                };
    
        return userRepository.findAll(specification);
    
    }
    

    首先我们添加 name LIKE %text% where表达式的一部分。

    接下来,我们检查 text 变量可以强制转换为 long 是的。如果可以,则从字符串中获取长值并将其添加到where查询。

    最后我们检查 文本 变量可以转换为布尔值。如果可以,那么我们也将该检查添加到查询中。

    例如,如果 文本 变量是 测试1 在哪里

    WHERE name LIKE '%test1%;
    

    如果 文本 变量是 那么在哪里

    WHERE name LIKE '%true%' OR is_active = true;
    

    最后,如果 文本 变量是 德意志北方银行 那么在哪里

    WHERE name LIKE '%12%' OR id = 12;
    

    注: 我补充说 cb.lower(root.get("name")) text.toLowerCase() 当我们按名称搜索时,为了使搜索不区分大小写。