spring data jpa 自定义分页插件

16 篇文章 0 订阅

实例

 (1)entity代码:

package com.skyline.study.webdemo1.entity;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * Created by Skyline on 2016/10/10.
 */
@Entity
@Table(name="testEntity")
public class TestEntity {

    @Id
//    @GeneratedValue(strategy = GenerationType.AUTO)
    @GenericGenerator(name="idGenerator", strategy="uuid") //这个是hibernate的注解/生成32位UUID
    @GeneratedValue(generator="idGenerator")
    public String id;
    @NotNull
    public String name;
    public String description;
    public Date createTime;
}


(2)持久层代码:

通用自定义持久层接口:

package com.skyline.study.webdemo1.dao.jpa.base;

import org.springframework.data.domain.Page;

import javax.persistence.criteria.CriteriaQuery;
import java.io.Serializable;

/**
 * 自定义方法
 * Created by Skyline on 2017/1/11.
 */
public interface BaseRepositoryCustom<T, ID extends Serializable>{
    void say(String s);
    Page<T> getPage(Class rootCls, CriteriaQuery<T> criteria, int pageNo, int pageSize);
}



通用自定义持久层接口实现:

package com.skyline.study.webdemo1.dao.jpa.base;

import com.skyline.study.webdemo1.dao.base.Pagination;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;

/**
 * Created by Skyline on 2017/1/11.
 */
@Repository
public class BaseRepositoryCustomImpl<T,ID extends Serializable> implements BaseRepositoryCustom<T,ID> {

    @PersistenceContext
    protected EntityManager em;

    @Override
    public void say(String s) {
        System.out.println(getClass() + " say '" + s + "'");
    }

    @Override
    public Page<T> getPage(Class rootCls, CriteriaQuery<T> criteria, int pageNo, int pageSize) {

        //count
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Long> criteriaC = builder.createQuery(Long.class);
        Root root = criteriaC.from(rootCls);
        criteriaC.select(builder.count(root));
        criteriaC.where(criteria.getRestriction());
        List<Long> totals = em.createQuery(criteriaC).getResultList();
        Long total = 0L;
        for (Long element : totals) {
            total += element == null ? 0 : element;
        }

        //content
        TypedQuery<T> query = em.createQuery(criteria);
        query.setFirstResult((pageNo - 1) * pageSize);
        query.setMaxResults(pageSize);
//        List<T> content = query.getResultList();
        List<T> content = total > query.getFirstResult() ? query.getResultList() : Collections.<T> emptyList();

        Pagination<T> pagination = new Pagination(pageNo, pageSize, total);
        pagination.setContent(content);
        return pagination;
    }
}


 备注:getPage()方法就是自定义的分页接口。


(3)TestEntity的持久层代码:


TestEntity持久层自定义方法接口:定义自定义方法。采用原生的EntityManager自定义方法实现。

package com.skyline.study.webdemo1.dao.jpa;

import com.skyline.study.webdemo1.entity.TestEntity;
import com.skyline.study.webdemo1.vo.TestEntityPageQuery;
import org.springframework.data.domain.Page;

import java.util.List;

/**
 * Created by Skyline on 2017/1/11.
 */
public interface TestEntityRepositoryCustom {
    void hello();
    Page<TestEntity> getPage(TestEntityPageQuery query);
    List<TestEntity> getList(TestEntityPageQuery query);
}

自定义方法接口实现:

package com.skyline.study.webdemo1.dao.jpa;

import com.skyline.study.webdemo1.dao.jpa.base.BaseRepositoryCustomImpl;
import com.skyline.study.webdemo1.entity.TestEntity;
import com.skyline.study.webdemo1.vo.TestEntityPageQuery;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Repository;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义方法的实现
 * Created by Skyline on 2017/1/11.
 */
@Repository
public class TestEntityRepositoryImpl extends BaseRepositoryCustomImpl<TestEntity,String> implements TestEntityRepositoryCustom {

    @Override
    public void hello() {
        System.out.println("entityManger:" + em);
        System.out.println("hello!>>>>>>");
    }

    @Override
    public Page<TestEntity> getPage(TestEntityPageQuery pageQuery) {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<TestEntity> criteria = builder.createQuery(TestEntity.class);
        Root<TestEntity> root = criteria.from(TestEntity.class);
        criteria.select(root);
        List<Predicate> predicates = new ArrayList<>();
        if(pageQuery.name != null) {
            predicates.add(builder.like(root.get("name"), "%" + pageQuery.name + "%"));
        }
        if (pageQuery.startTime != null && pageQuery.endTime != null) {
            predicates.add(builder.between(root.get("createTime"), pageQuery.startTime, pageQuery.endTime));
        }
        Predicate[] preArr = new Predicate[predicates.size()];
        predicates.toArray(preArr);
        criteria.where(preArr);
        criteria.orderBy(builder.desc(root.get("createTime")));

        Page<TestEntity> page = getPage(TestEntity.class, criteria, pageQuery.pageNo, pageQuery.pageSize);

        return page;
    }

    @Override
    public List<TestEntity> getList(TestEntityPageQuery pageQuery) {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<TestEntity> query = builder.createQuery(TestEntity.class);
        Root<TestEntity> root = query.from(TestEntity.class);
        query.select(root);

        List<Predicate> predicates = new ArrayList<>();
        if(pageQuery.name != null) {
            predicates.add(builder.like(root.get("name"), "%" + pageQuery.name + "%"));
        }
        if (pageQuery.startTime != null && pageQuery.endTime != null) {
            predicates.add(builder.between(root.get("createTime"), pageQuery.startTime, pageQuery.endTime));
        }
        query.where(predicates.toArray(new Predicate[]{}));
        query.orderBy(builder.desc(root.get("createTime")));
        return em.createQuery(query).getResultList();
    }
}


备注:hibernate jpa 默认查找 持久层接口名 + 'Impl' 这个类作为自定义方法的实现,如TestEntityRepositoryImpl中的方法作为TestEntityRepository 接口中自定义方法的实现。


最终TestEntity持久层接口:

package com.skyline.study.webdemo1.dao.jpa;

import com.skyline.study.webdemo1.dao.jpa.base.BaseRepositoryCustom;
import com.skyline.study.webdemo1.entity.TestEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/**
 * Created by Skyline on 2017/1/10.
 */
public interface TestEntityRepository extends JpaRepository<TestEntity,String>, JpaSpecificationExecutor<TestEntity>, BaseRepositoryCustom<TestEntity,String>,TestEntityRepositoryCustom {
    TestEntity findByName(String name);
}


备注:

hibernate jpa会自动为Repository接口的子接口生成代理类。默认是SimpleJpaRepository。继承JpaSpecificationExecutor类是为了让hibernate jpa自带的分页方法支持条件查询。

jpa依据规范化的方法名称或者通过注解如@Query指定的sql自动生成对应的实现方法。



(4)Service层代码:

TestEntityService代码:

package com.skyline.study.webdemo1.service;

import com.skyline.study.webdemo1.entity.TestEntity;
import com.skyline.study.webdemo1.vo.TestEntityPageQuery;
import org.springframework.data.domain.Page;

import java.util.List;

/**
 * Created by Skyline on 2016/10/14.
 */
public interface TestEntityService {
    void save(TestEntity testEntity);
    void delete(String id);
    TestEntity getByName(String name);
    Page<TestEntity> getPage(TestEntityPageQuery pageQuery);
    Page<TestEntity> getPageCustom(TestEntityPageQuery pageQuery);
    List<TestEntity> getList(TestEntityPageQuery pageQuery);
    List<TestEntity> getAll();

}


TestEntityServiceImpl

package com.skyline.study.webdemo1.service;

import com.skyline.study.webdemo1.dao.jpa.TestEntityRepository;
import com.skyline.study.webdemo1.entity.TestEntity;
import com.skyline.study.webdemo1.vo.TestEntityPageQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Skyline on 2016/10/14.
 */
@Service
public class TestEntityServiceImpl implements TestEntityService {

    @Resource
    private TestEntityRepository testEntityRepository;

    @Override
    public void save(TestEntity testEntity) {
        testEntityRepository.save(testEntity);
    }

    @Override
    public void delete(String id) {
        testEntityRepository.delete(id);
    }

    @Override
    public TestEntity getByName(String name) {
        return testEntityRepository.findByName(name);
    }

    /**
     * 采用hibernate jpa 自带的分页方法
     * @param pageQuery
     * @return
     */
    @Override
    public Page<TestEntity> getPage(TestEntityPageQuery pageQuery) {
        PageRequest pageRequest = new PageRequest(pageQuery.pageNo - 1, pageQuery.pageSize);
        Specification spe = new Specification<TestEntity>() {
            @Override
            public Predicate toPredicate(Root<TestEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

                List<Predicate> list = new ArrayList<>();
                if(pageQuery.name != null) {
                    list.add(cb.like(root.get("name"), "%" + pageQuery.name + "%"));
                }
                if (pageQuery.startTime != null && pageQuery.endTime != null) {
                    list.add(cb.between(root.get("createTime"), pageQuery.startTime, pageQuery.endTime));
                }
                query.orderBy(cb.desc(root.get("createTime")));
                Predicate[] predicates = new Predicate[list.size()];
                predicates = list.toArray(predicates);
                return cb.and(predicates);
            }
        };

        return testEntityRepository.findAll(spe, pageRequest);
    }

    /**
     * 采用自定义分页方法
     * @param pageQuery
     * @return
     */
    @Override
    public Page<TestEntity> getPageCustom(TestEntityPageQuery pageQuery) {
        return testEntityRepository.getPage(pageQuery);
    }

    @Override
    public List<TestEntity> getList(TestEntityPageQuery pageQuery) {
        return testEntityRepository.getList(pageQuery);
    }

    @Override
    public List<TestEntity> getAll() {
        return testEntityRepository.findAll();
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值