默认的 JPA 可以做简单的查询,当我们遇到多条件时怎么动态的来查询数据,这里使用 Specification 来解决这个问题
一、使用
Dao 接口需要继承 JpaRepository 之外,还需要继承 JpaSpecificationExecutor
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.info.thinkcloud.common.entity.rbac.User;
public interface UserRepo extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
}
JpaSpecificationExecutor 默认有以下这些方法:
// 根据条件查询获取一条数据
T findOne(Specification<T> spec);
// 根据条件查询获取全部数据
List<T> findAll(Specification<T> spec);
// 根据条件分页查询数据,pageable设定页码、一页数据量,同时返回的是Page类对象,可以通过getContent()方法拿到List集合数据
Page<T> findAll(Specification<T> spec, Pageable pageable);
// 根据条件查询并返回排序后的数据
List<T> findAll(Specification<T> spec, Sort sort);
// 获取满足当前条件查询的数据总数
long count(Specification<T> spec);
实现多条件的查询:
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.info.thinkcloud.common.entity.rbac.User;
import com.info.thinkcloud.common.repository.rbac.UserRepo;
@Service
public class UserService {
@Autowired
private UserRepo userRepo;
/**
* JPA动态查询
*/
public List<User> find(User user) {
// Specification查询构造器
Specification<User> specification = new Specification<User>() {
private static final long serialVersionUID = 1L;
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
// 添加搜索条件
if (null != user.getId()) {
predicates.add(criteriaBuilder.equal(root.get("id"), user.getId())); // id是表字段对应实体表属性
}
if (StringUtils.isNotBlank(user.getName())) {
predicates.add(criteriaBuilder.like(root.get("name"), "%" + user.getName() + "%"));
}
// 把搜索条件连接(AND)起来
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
return userRepo.findAll(specification);
}
}