欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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);
    }
}
相关标签: jpa