spring data jpa 条件分页查询

PS:一半转载,一半自己的用例

作者:javaniu

链接:https://www.zhihu.com/question/37873032/answer/73991650
来源:知乎
著作权归作者所有,转载请联系作者获得授权。( PS:暂时没有知乎账号,所以没有联系原作者,请原作者见谅!

springdata jpa总结的查询方法有如下:

  1. findOneByName按用户名查询User对象
  2. findAllByLargeThanId查询id号大于指定参数值的User对象列表,分页Page返回
  3. findAllByIdAndName查询id和用户名等于指定参数值的User对象,可以通过多个Predicate来查询
  4. findAllByLikeName模糊分页查询用户名,like查询
  5. findAllByInIds查询指定的id集合用户对象列表
  6. findAllByIds通过原生sql查询指定的用户id对象列表
  7. findAllByName通过JPA query查询用户名等于指定值的用户对象
  8. 多个排序语法: Sort sort = new Sort(Direction.DESC, "sort").and(new Sort(Direction.DESC, "id"));
package com.zuidaima.springdata.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.zuidaima.springdata.entity.User;
import com.zuidaima.springdata.repository.UserRepository;
import com.zuidaima.springdata.service.UserService;

/**
 * *@author javaniu 2013-06-04 22:27:23
 */

@Service
public class UserServiceImpl implements UserService {

	@Resource
	public UserRepository userRepository;

	@Override
	public User findOneByName(final String name) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
				Predicate _name = criteriaBuilder.equal(root.get("name"), name);
				return criteriaBuilder.and(_name);
			}
		};
		return userRepository.findOne(specification);
	}

	@Override
	public Page<User> findAllByLargeThanId(final Long id, int page, int count,
			Sort sort) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
				Path<Long> $id = root.get("id");
				Predicate _id = criteriaBuilder.gt($id, id);
				return criteriaBuilder.and(_id);
			}
		};
		Pageable pageable = new PageRequest(page - 1, count, sort);
		return userRepository.findAll(specification, pageable);
	}

	@Override
	public User findAllByIdAndName(final Long id, final String name) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicates = new ArrayList<Predicate>();
				Path<Long> $id = root.get("id");
				Predicate _id = criteriaBuilder.equal($id, id);
				predicates.add(_id);
				Path<Long> $name = root.get("name");
				Predicate _name = criteriaBuilder.equal($name, name);
				predicates.add(_name);
				return criteriaBuilder.and(predicates
						.toArray(new Predicate[] {}));
			}
		};
		return userRepository.findOne(specification);
	}

	@Override
	public Page<User> findAllByLikeName(final String name, int page, int count) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
				Path<String> _name = root.get("name");
				Predicate _key = criteriaBuilder.like(_name, "%" + name + "%");
				return criteriaBuilder.and(_key);
			}
		};
		Sort sort = new Sort(Direction.DESC, "id");
		Pageable pageable = new PageRequest(page - 1, count, sort);
		return userRepository.findAll(specification, pageable);
	}

	@Override
	public Page<User> findAllByInIds(final List<Long> ids) {
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
				return criteriaBuilder.in(root.get("id")).value(ids);
			}
		};
		int page = 1;
		int count = ids.size();
		Sort sort = new Sort(Direction.DESC, "id");
		Pageable pageable = new PageRequest(page - 1, count, sort);
		return userRepository.findAll(specification, pageable);
	}

	@Override
	public List<User> findAllByIds(List<Long> ids) {
		return userRepository.findAllByIds(ids);
	}

	@Override
	public User findAllByName(String name) {
		return userRepository.findAllByName(name);
	}

}
=====================================  华丽分割线  ===============================================
以下是我在项目中的实际运用:
	1.实体类:GsTest(这里就不贴代码了)
	2.Dao层:
	@Repository
	public interface GsTestDao extends JpaRepository,JpaSpecificationExecutor{
	 
	}
	3.Service层 :(也可以是单独的某个参数,详情见上面),page:页数,conut:每页的条数,sort:排序
	Page findOneByName(GsTest gsTest,int page,int count,Sort sort);
	4.ServiceImpl层
	//分頁  条件为年龄和 姓名。
	@Override
	public Page findOneByName(final GsTest gsTest,int page,int count,Sort sort) {
		Specification specification = new Specification() {
			@Override
			public Predicate toPredicate(Root root,
					CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
				List predicates = new ArrayList();
				//参数非空判断。不为空则加此条件
				if (!gsTest.getAge().isEmpty()) {
					Predicate _age = criteriaBuilder.equal(root.get("age"), gsTest.getAge());
					predicates.add(_age);
					System.out.println("_age:"+gsTest.getAge().isEmpty());
				}
				Predicate _name = criteriaBuilder.equal(root.get("name"), gsTest.getName());
				predicates.add(_name);
				
				//return criteriaBuilder.and(_name);
				return criteriaBuilder.and(predicates.toArray(new Predicate[]{}));
			}
		};
	4.controller:控制层
	/**
				 * @param gsTestDto 实体,用来接收传来JSON类型参数
		 * @param pageNumber  页数
		 * @param pageSize   条数
		 * @return
		 */
		@RequestMapping(value="/fin",method = RequestMethod.POST)
		@ResponseBody
		public  Page findTest(@RequestBody GsTestDto gsTestDto,@RequestParam(value = "page", defaultValue = "1") int pageNumber,
				@RequestParam(value = "size", defaultValue = Constants.PAGE_SIZE_10) int pageSize){
			GsTest gsTest = new GsTest();
			gsTest=converterIn.convertIn(gsTestDto);
			System.out.println("GsTestDto:"+gsTest);
			//排序
			Sort sort = new Sort(Direction.ASC, "id");
			Page findOneByName = gsTestDaoService.findOneByName(gsTest,pageNumber,pageSize,sort);


			return findOneByName;
		}
	到此,条件分页就完成了。看看测试结果:
	我用的是 谷歌的Postman来进行测试:
	1.传参:
  	{
   	 "name": "jak"
	}
	结果:
{
  "content": [
    {
      "id": 3,
      "properties_string": null,
      "name": "jak",
      "age": "21",
      "sex": "女",
      "status": "1",
      "certime": "2013-05-11 09:00:00"
    },
    {
      "id": 4,
      "properties_string": null,
      "name": "jak",
      "age": "21",
      "sex": "女",
      "status": "1",
      "certime": "2013-05-11 09:00:00"
    },
    {
      "id": 5,
      "properties_string": null,
      "name": "jak",
      "age": "21",
      "sex": "女",
      "status": "1",
      "certime": "2013-05-11 09:00:00"
    }
  ],
  "size": 10,
  "number": 0,
  "sort": [
    {
      "direction": "ASC",
      "property": "id",
      "ascending": true
    }
  ],
  "lastPage": true,
  "firstPage": true,
  "totalPages": 1,
  "totalElements": 3,
  "numberOfElements": 3
}
	2.传错误的参数:
{
    "name": "jak",
    "age":"22"
}
	结果:
{
  "content": [],
  "size": 10,
  "number": 0,
  "sort": [
    {
      "direction": "ASC",
      "property": "id",
      "ascending": true
    }
  ],
  "lastPage": true,
  "firstPage": true,
  "totalPages": 0,
  "totalElements": 0,
  "numberOfElements": 0
}
	可以看得到 查不到的时候。content 是空值!
	到此,简单的条件分页查询就完成了,我也是小白,不妥之处见谅!

===============2017年3月2日10:28:46=======  华丽分割线  ===============================================
注:接着上面的
实体类:prid
         实体类中有一个时间属性:
              private Date beginTime;               
               private Date endTime;

JPA 查询运用的时候应该是:
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
Predicate dueTime = criteriaBuilder.between(root.get("dueTime"),sdf2.parse(prid.getBeginTime()),sdf2.parse(prid.getEndTime()));

注:parse()返回的是一个Date类型数据

你可能感兴趣的:(java,spring,data,jpa)