gpt4 book ai didi

java - JPA 搜索字符串、长整数和 boolean 值

转载 作者:行者123 更新时间:2023-11-29 05:54:22 25 4
gpt4 key购买 nike

我有一个 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 应用于 LongBoolean

例如,如果我尝试按“testSearchValue”进行过滤,我会收到此异常:

java.lang.IllegalArgumentException: Parameter value [%testSearchValue%] did not match expected type [java.lang.Long (n/a)

不幸的是,CASTCONVERT 对我不起作用。

那么有什么解决办法吗?

一些细节

我向此 API 发送一个 GET 请求:

@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);
}

所以:

据我所知,问题的基本点是将 LongBoolean 表示为 String
也许使用 nativeQuery 会更好?如果是这样,那么您能给我一些关于如何将 CAST()CONVERT()LIKE 子句一起使用的提示吗?

最佳答案

你考虑过Specifications的用法吗? ?

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

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);

}

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

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

最后我们检查 text 变量是否可以转换为 boolean 值。如果可以,那么我们也将该检查添加到查询中。

例如,如果 text 变量的值为 test1 where 部分将是

WHERE name LIKE '%test1%;

如果 text 变量的值为 true 那么 where 部分将是

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

最后,如果 text 变量的值为 12 那么 where 部分将是

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

注意:当我们按名称搜索时,我将 cb.lower(root.get("name"))text.toLowerCase() 添加到部分以进行搜索不敏感。

关于java - JPA 搜索字符串、长整数和 boolean 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51113509/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com