我有以下的请求给管理员和管理员
@PostMapping
public responseDto search(@RequestBody SearchUserRequestDto request){
userService.search(request);
}
java prettyprint-override">public class SearchUserRequestDto {
private Long userId;
private String firstName;
private String lastName;
private String role;
private String userType;
}
我想用上面Dto中不为空的字段搜索用户存储库。
示例:如果firstName是“john”,lastName是“smith”,其余字段为空,那么我必须在存储库中搜索firstName是“john”,lastName是“smith”的所有记录(不是或)
我还必须为响应执行分页
我是Spring靴新手,有人能建议我怎么做吗?
如果您使用的是JPA,我建议您使用Spring数据JPA和规范API。当我最初研究Spring Boot和Spring数据时,我看到推广的唯一真正方法是Spring数据Rest,这对我来说太神奇了。
我个人喜欢让控制器调用服务上的方法(可重用业务逻辑层,基本上是门面模式)。这些服务最终调用Spring数据存储库。
考虑<代码>用户< /代码>对象
public class User{
String firstName;
String lastName;
}
假设我们有一个UserController
来处理User
资源的REST请求。此控制器将带有UserSearchCriteria
的请求转换为Spring数据页面
import org.springframework.data.domain.Page;
public class UserController{
@Autowired
UserService userService;
@RequestMapping(path = "/users", method = RequestMethod.GET)
Page<User> getAll(HttpServletRequest request, UserSearchCriteria searchCriteria){
return userService.findAllUsers(searchCriteria);
}
}
UserSearchCriteria
是您的客户端将作为查询参数传递的搜索参数类型,如GET /users? firstName=misa
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.PageRequest;
public class UserSearchCriteria {
UserSearchCriteria(){
super();
sort = "lastName";
}
Integer size;
Integer page;
String sort;
String sortDir;
String firstName;
String lastName;
Sort buildSort(){
return new Sort(new Sort.Order(Sort.Direction.ASC, sort).ignoreCase());
}
PageRequest toPageRequest(){
if(size == null){
size = Integer.MAX_VALUE; // may or may not be a good idea for your usecase
}
return new PageRequest(page, size, buildSort());
}
}
PageRequest
和Sort
是Spring数据项目的一部分。在我的项目中,我让排序和分页存在于AbstractSearchCriteria
对象中,以便于重用,我的所有搜索标准都扩展了这个对象,但上面的演示更简单。
在
UserService
层中,我将委托给我的存储库(我还可以检查访问要求、设置默认值等)。
import org.springframework.data.domain.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public class UserService{
@Autowired
UserRepository userRepository;
Page<User> findAllUsers(UserSearchCriteria userSearchCriteria){
if(userSearchCriteria == null){
userSearchCriteria = new UserSearchCriteria();
}
return userRepository.findAll(UserSearchSpecification.findByCriteria(userSearchCriteria), userSearchCriteria.toPageRequest());
}
}
UserSearchSpecification
使用Specification
API动态地将搜索添加到JPA调用中,我发现这比直接使用Criteria
API更简洁。
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
public class UserSearchSpecification{
public static Specification<User> findByCriteria(final UserSearchCriteria searchCriteria){
return new Specification<User>() {
@Override
Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
// if firstName in criteria, do an uppercase prefix match
if(searchCriteria.firstName != null){
predicates.add(
cb.like(
cb.upper(root.get("firstName")),
"%" + searchCriteria.lastName.toUpperCase()
)
);
}
// if lastName in criteria, do an uppercase prefix match
if(searchCriteria.lastName != null){
predicates.add(
cb.like(
cb.upper(root.get("lastName")),
"%" + searchCriteria.lastName.toUpperCase()
)
);
}
if(predicates.size() > 0){
return cb.and(predicates.toArray());
}else{
return null;
}
}
}
}
}
这使您可以轻松地检查从rest调用传递的params(
UserSearchSpeation
上的属性),并动态地构建数据库调用的限制。最后,我选择将和
每个谓词放在一起,但是您可以在这里做任何您想做的事情。您还可以检查相等而不是like,大于/小于等。
最后,请注意,此规范传递到
UserService.findAllUser
方法中的UserRepository
。这是一个Spring Data存储库:
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface UserRepository extends PagingAndSortingRepository<User, Long>, JpaSpecificationExecutor<User>{
}
通常,您只需要在Spring这样的数据存储库中扩展某些接口。Spring数据可以处理引擎盖下的其他数据。重要的是要注意
PagingAndSortingRepository
的扩展,它处理分页和排序方面,以及JpaSpecificationExecutor
的扩展,它接受规范
对象并生成正确的查询。
这看起来像是很多代码,但随着代码库的增长,这对我来说扩展得非常好。一旦有了规范,就可以轻松地向
搜索条件
对象添加新字段,并通过检查新字段和创建谓词
在规范中添加新限制。
正如@mandar dharurkar所建议的,你可以使用org。springframework。数据领域可分页,但对于条件搜索,您可以使用以下内容:,
@Query("SELECT u FROM User u WHERE (:name is null or u.name = :name) and (:lastname is null"
null + " or u.lastname= :lastname)")
Page<User> search(@Param("name") String name, @Param("lastname") String lastname, Pageable pageable);
问题内容: 我正在使用最新版本的elasticsearch-php以及最新版本的MongoDB和ElasticSearch。 我需要对可以包含一个或多个值的多个字段进行搜索。例: country_code应为NL,BE或DE,并且类别应包含AA01,BB01,CC02或ZZ11 我以为我会按照以下方式解决它(PHP): 但是结果甚至还不能接近我期望返回的数据。 有时 $ countries 和/或
问题内容: 现在,我有一个通过KeyReleased事件实现的搜索textField,当我开始键入“ Andrew”中的“ An”时,并在我准确键入(caseSensitive)我要输入的名称后,找不到/更新jTable。找。 因此,我想要从该站点实现Filtering方法,但是我遇到了很大的问题。在执行以下操作并删除了“旧的” KeyReleased事件之后,当我在文本字段“ txt_searc
问题内容: 我第一次使用Postgresql,并且试图在我的网站中创建一个搜索引擎。我有这张桌子: 然后我为表的每个字段创建了一个索引(这是正确的方法吗?或者我可以为所有字段创建一个索引?): 现在,如果我想在每个索引中搜索一个单词,SQL查询是什么? 我尝试了这个,它的工作原理: 是否存在更好的方法来做到这一点?我可以搜索多个吗?我的一个朋友提出了一个解决方案,但这是针对MySQL数据库的: P
问题内容: 我正在构建一个简单的 搜索 算法,我想 用空格 打破我的 字符串 ,并在其上搜索数据库,如下所示: 这可能吗? 问题答案: 是的,您可以使用SQL 运算符来搜索多个绝对值: 如果要使用,则需要改为使用: 使用(如您所尝试的)要求所有条件为真,使用至少需要一个条件为真。
我有一个如下的模型: 它填充了一些数据: 我需要合并/加入一个集合(不是queryset): 所以基本上,当我用这个元组列表搜索这个模型时,第0行和第2行应该返回。 目前,我的解决方法是将 读取到数据帧中,并与元组列表进行合并,并将 ID 传递给 。我还尝试迭代列表并在每个元组上调用 但它非常慢。这个清单相当大。 当我尝试按照当前答案的建议链接Q时,它抛出了一个OperationalError(太
如果我想搜索那些名字中包含巴黎的地方,我会做以下操作: 这样我就能看到所有有巴黎这个名字的地方。 然而,我如何能够搜索到其他标准的地方,如 null 在Cloud Firestore中这甚至是可能的吗?如果没有的话,有没有其他方法可以做到这一点?