您的位置:首页 > 编程语言 > Java开发

spring data jpa 条件分页查询

2016-12-02 10:08 721 查看
PS:一半转载,一半自己的用例

作者:javaniu

链接:https://www.zhihu.com/question/37873032/answer/73991650

来源:知乎

著作权归作者所有,转载请联系作者获得授权。(PS:暂时没有知乎账号,所以没有联系原作者,请原作者见谅!)

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

findOneByName按用户名查询User对象
findAllByLargeThanId查询id号大于指定参数值的User对象列表,分页Page返回
findAllByIdAndName查询id和用户名等于指定参数值的User对象,可以通过多个Predicate来查询
findAllByLikeName模糊分页查询用户名,like查询
findAllByInIds查询指定的id集合用户对象列表
findAllByIds通过原生sql查询指定的用户id对象列表
findAllByName通过JPA query查询用户名等于指定值的用户对象
多个排序语法: 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类型数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: