Spring Data JPA 多条件查询
程序员文章站
2022-04-25 19:53:57
...
Spring Data JPA 查询很方便,但做搜索功能时,条件都是未知的,并不能用方法命名的方式查询,自己写JPQL,用表达式的方式处理也不靠谱,条件多了简直就是作死,以前写过下面的代码:
SELECT * FROM UserModel AS u WHERE u.sex = :sex AND u.age = :age
变化后
SELECT * FROM UserModel AS u WHERE (u.sex = :sex OR :sex == null) AND (u.age = :age OR :age == null)
正确解决办法是 JpaSpecificationExecutor 接口,这个接口中有5个方法
package org.springframework.data.jpa.repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
public interface JpaSpecificationExecutor<T> {
T findOne(Specification<T> var1);
List<T> findAll(Specification<T> var1);
Page<T> findAll(Specification<T> var1, Pageable var2);
List<T> findAll(Specification<T> var1, Sort var2);
long count(Specification<T> var1);
}
Dao
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.github.ckwen.je.spring.boot.security.model.EmployeeModel;
public interface EmployeeRepository extends JpaRepository<EmployeeModel, String>, JpaSpecificationExecutor<EmployeeModel> {
}
Service
@Override
public List<EmployeeModel> findSearch(EmployeeModel model) {
Assert.notNull(model);
List<EmployeeModel> result = employeeRepository.findAll(new Specification<EmployeeModel>() {
@Override
public Predicate toPredicate(Root<EmployeeModel> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<Predicate>();
if (StringUtils.isNoneBlank(model.getName())) {
list.add(cb.like(root.get("name").as(String.class), "%" + model.getName() + "%"));
}
if (model.getGender() != null) {
list.add(cb.equal(root.get("gender").as(GenderType.class), model.getGender()));
}
if (StringUtils.isNotBlank(model.getTelPhone())) {
list.add(cb.like(root.get("telPhone").as(String.class), "%" + model.getTelPhone() + "%"));
}
if (model.getDepartment() != null && model.getDepartment().getCode() != null) {
list.add(cb.equal(root.get("department").as(DepartmentModel.class), model.getDepartment()));
}
Predicate[] p = new Predicate[list.size()];
return cb.and(list.toArray(p));
}
});
return result;
}
Junit
@Autowired
private EmployeeService employeeService;
@Test
public void test() {
EmployeeModel model = new EmployeeModel();
model.setName("33");
model.setGender(GenderType.MALE);
List<EmployeeModel> rs = employeeService.findSearch(model);
for (EmployeeModel employeeModel : rs) {
System.out.println(employeeModel);
}
}
@Test
public void test1() {
EmployeeModel model = new EmployeeModel();
model.setDepartment(new DepartmentModel("AAA"));
List<EmployeeModel> rs = employeeService.findSearch(model);
for (EmployeeModel employeeModel : rs) {
System.out.println(employeeModel);
}
}
推荐阅读
-
Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页示例
-
Spring Data JPA+kkpager实现分页功能实例
-
Spring Data JPA实现动态条件与范围查询实例代码
-
详解Spring Data JPA动态条件查询的写法
-
Spring boot中使用Spring-data-jpa方便快捷的访问数据库(推荐)
-
详解Spring Data Jpa 模糊查询的正确用法
-
Spring Data Jpa 复合主键的实现
-
Spring Data JPA 建立表的联合主键
-
使用Spring Data JPA的坑点记录总结
-
Spring Data Jpa 自动生成表结构的方法示例