实例
(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(); } }