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<GsTest, Long>,JpaSpecificationExecutor<GsTest>{
	 
	}
	3.Service层 :(也可以是单独的某个参数,详情见上面),page:页数,conut:每页的条数,sort:排序
	Page<GsTest> findOneByName(GsTest gsTest,int page,int count,Sort sort);
	4.ServiceImpl层
	//分頁  条件为年龄和 姓名。
	@Override
	public Page<GsTest> findOneByName(final GsTest gsTest,int page,int count,Sort sort) {
		Specification<GsTest> specification = new Specification<GsTest>() {
			@Override
			public Predicate toPredicate(Root<GsTest> root,
					CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicates = new ArrayList<Predicate>();
				//参数非空判断。不为空则加此条件
				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<GsTest> 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<GsTest> 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.<Date>get("dueTime"),sdf2.parse(prid.getBeginTime()),sdf2.parse(prid.getEndTime()));

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

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
使用Spring Data JPA进行分页查询需要遵循以下步骤: 1. 定义Repository接口,继承JpaRepository或其它Spring Data提供的Repository接口。 ```java @Repository public interface UserRepository extends JpaRepository<User, Long> { } ``` 2. 在Controller中注入Repository,并使用Pageable参数注入分页参数。 ```java @Autowired private UserRepository userRepository; @GetMapping("/users") public Page<User> getUsers(Pageable pageable) { return userRepository.findAll(pageable); } ``` 3. 在前端页面中传递分页参数,例如使用thymeleaf的分页标签: ```html <div class="pagination"> <ul> <li th:class="${users.first} ? disabled"><a th:href="@{${#httpServletRequest.requestURI}(page=0,size=${users.size},sort=${users.sort})}">«</a></li> <li th:class="${users.number == 0} ? disabled"><a th:href="@{${#httpServletRequest.requestURI}(page=${users.number - 1},size=${users.size},sort=${users.sort})}">‹</a></li> <li th:each="i : ${#numbers.sequence(0, users.totalPages - 1)}" th:class="${users.number == i} ? active"><a th:href="@{${#httpServletRequest.requestURI}(page=${i},size=${users.size},sort=${users.sort})}" th:text="${i + 1}"></a></li> <li th:class="${users.number == users.totalPages - 1} ? disabled"><a th:href="@{${#httpServletRequest.requestURI}(page=${users.number + 1},size=${users.size},sort=${users.sort})}">›</a></li> <li th:class="${users.last} ? disabled"><a th:href="@{${#httpServletRequest.requestURI}(page=${users.totalPages - 1},size=${users.size},sort=${users.sort})}">»</a></li> </ul> </div> ``` 以上就是使用Spring Data JPA进行分页查询的基本步骤,可以根据自己的需求进行更加灵活的配置和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sun_逸圣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值