使用JPA的Specification可以极大的减少service的代码重复率,实现代码复用。并且降低你的reposity中的方法量。
步骤1:继承JpaRepository
public interface ArticleMainRepository extends JpaRepository<ArticleMain, Long>{
/**
*ArticleMain是自定义JPA实体类类名
*/
Page<ArticleMain> findAll(Specification<ArticleMain> spec, Pageable pageable);
}
步骤2:直接写你的service
public class ArticleServiceImpl implements ArticleService {
@Autowired
ArticleMainRepository articleMainRepo;
@Override
public Page<ArticleDto> findArticle(int page, int size, int state, String openId, String title, String categoryId) {
dataPage = articleMainRepo.findAll(new Specification<ArticleMain>() {
@Override
public Predicate toPredicate(Root<ArticleMain> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
/**
上面部分复写方法什么的都是硬写法,照抄
*/
if(条件1){
/**
equal就相当于 SQL的where,两个predicates.add 相当于where and
root.get("param").as(xx.class),state param就是你要检索的实体类中的参数名,后面的xx就是这个字段的类型。这两个必须和实体类保持一致,即和ArticleMain保持一致。state是传入参数相当于where a.id=?1 的?1.
*/
predicates.add(criteriaBuilder.equal(root.get("state").as(Integer.class),state));
predicates.add(criteriaBuilder.equal(root.get("state").as(Integer.class),StateEnum.ARTICLE_RELEASE.getValue()));
}
if(条件2){
predicates.add(criteriaBuilder.like(root.get("title").as(String.class),"%"+title+"%"));
predicates.add(criteriaBuilder.equal(root.get("state").as(Integer.class),StateEnum.ARTICLE_RELEASE.getValue()));
}
/**
下面的照抄
*/
Predicate[] pre = new Predicate[predicates.size()];
query.where( predicates.toArray( pre ) );
return criteriaBuilder.and( predicates.toArray( pre ) );
}
/**
后端的page从0开始,前端传入的一般从1开始,这里做一个-1
*/
},PageRequest.of(page-1, size, Sort.by(sortOrder, sortBy)));
}
}