Spring Boot 中使用 Spring-data-jpa 重写分页接口并实现动态传条件以及排序字段
2018-07-25 16:09
936 查看
这篇文章讲的是在spring boot 中使用 spring data jpa 重写接口类 并实现自定义分页查询这里不仅包含了查询条件还包含了多个字段排序,希望给你在开发中带来帮助,这里主要是在原来的分页查询方法上做了封装,可能只满足了部分需求,在后续会说到原生sql怎么做封装。
源码地址 https://github.com/xutang123/wanshun
基本的数据结构
自定义注解Sqlfield定义
[code]@Retention(RetentionPolicy.RUNTIME) public @interface Sqlfield { String name() default ""; }
常量类ConnectionFactory
[code]public class ConnectionFactory { /** * 字符串对象类型 * */ public static final String STRING_TYPE_CLASS = "class com.wanshun.cloud.wanshun.base.op.StringType"; /** * 整型对象类型 * */ public static final String NUMER_TYPE_CLASS = "class com.wanshun.cloud.wanshun.base.op.StringType"; /** * 获取对象值”git“头 * */ public static final String GET_NAME = "get"; /** * 正序 * */ public static final String DESC_TYPE = "DESC"; /** * 倒序 * */ public static final String ASC_TYPE = "ASC"; }
枚举类Symbol
[code]public enum Symbol { eq, greater, Less, like }
等于对象类EqClass
[code]public class EqClass { public Predicate symbolPunlic(Expression expression, Object object, CriteriaBuilder cb){ return cb.equal(expression, object.toString()); } }
其他符号的对象类基本类似。
自定义数据类型 NumerType
[code]public class NumerType { private Symbol op; private Integer value; public Symbol getOp() { return op; } public void setOp(Symbol op) { this.op = op; } public Integer getValue() { return value; } public void setValue(Integer value) { this.value = value; } }
[code]StringType 的value 为 String 类型
公共分页类 Base
[code]public class Base implements Serializable{ /** *<p> * 分页页码 *</p> * */ protected int page=0; /** *<p> * 分页每页条数 *</p> * */ protected int size=20; /** *<p> * 排序对象id:DESC,name,ASC *</p> * */ protected String sorting="id:DESC"; public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public String getSorting() { return sorting; } public void setSorting(String sorting) { this.sorting = sorting; } }
接口 BaseRepository
[code]@NoRepositoryBean public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> { boolean support(String modelType); Page<T> getPage(Object obj,Base var2); }
[code]类 BaseRepositoryFactoryBean
[code]public class BaseRepositoryFactoryBean <R extends JpaRepository<T, ID>, T, ID extends Serializable> extends JpaRepositoryFactoryBean<R, T, ID> { public BaseRepositoryFactoryBean(Class<? extends R> repositoryInterface) { super(repositoryInterface); } @Override protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) { return new MyRepositoryFactory(em); } private static class MyRepositoryFactory<T, ID extends Serializable> extends JpaRepositoryFactory { private final EntityManager em; public MyRepositoryFactory(EntityManager em) { super(em); this.em = em; } @Override protected Object getTargetRepository(RepositoryInformation metadata) { return new BaseRepositoryImpl<T, ID>((Class<T>) metadata.getDomainType(), em); } @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { return BaseRepositoryImpl.class; } } }
类 BaseRepositoryImpl
[code]public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> { private final Class<T> domainClass; @PersistenceContext protected EntityManager em; public BaseRepositoryImpl(Class<T> domainClass, EntityManager entityManager) { super(domainClass, entityManager); this.domainClass = domainClass; } @Override public boolean support(String modelType) { return domainClass.getName().equals(modelType); } /** * 自定义分页查询 * @obj 查询条件对象 * @var2 分页排序条件对象 * */ @Override public Page<T> getPage( final Object obj,Base var2) { Specification specification= new Specification<T>() { @Override public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicate = new ArrayList<>(); Field[] field = obj.getClass().getDeclaredFields(); for (int j = 0; j < field.length; j++) { // 遍历所有属性 String name = field[j].getName(); // String thename = name.substring(0, 1).toUpperCase() + name.substring(1); // 将属性的首字符大写,方便构造get,set方法 String type = field[j].getGenericType().toString(); // 获取属性的类型 try { Class clas = String.class; Symbol tyep = Symbol.eq; Object object = null; if (type.equals(ConnectionFactory.STRING_TYPE_CLASS)) { // 如果type是类类型,则前面包含"class ",后面跟类名 Method m = obj.getClass().getMethod(ConnectionFactory.GET_NAME + thename); StringType value = (StringType) m.invoke(obj); // 调用getter方法获取属性 if(value != null) { clas = String.class; tyep = value.getOp(); object = value.getValue(); } }else if (type.equals(ConnectionFactory.NUMER_TYPE_CLASS)) { // 如果type是类类型,则前面包含"class ",后面跟类名 Method m = obj.getClass().getMethod(ConnectionFactory.GET_NAME + thename); NumerType value = (NumerType) m.invoke(obj); // 调用getter方法获取属性 if(value != null) { clas = Integer.class; tyep = value.getOp(); object = value.getValue(); } }else { Method m = obj.getClass().getMethod(ConnectionFactory.GET_NAME + thename); object = m.invoke(obj); // 调用getter方法获取属性 } if (object != null && object != "") { Expression expression = root.get(name).as(clas); new PredicateNewClass(expression,object,cb); predicate.add(PredicateNewClass.map.get(tyep)); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } Predicate[] pre = new Predicate[predicate.size()]; return query.where(predicate.toArray(pre)).getRestriction(); } }; //多属性排序 List<Sort.Order> list = new ArrayList<>(); String[] op1 = var2.getSorting().split(","); for (String string:op1) { String[] op2= string.split(":"); Sort.Direction direction = Sort.Direction.DESC; if(ConnectionFactory.ASC_TYPE.equals(op2[1])){ direction = Sort.Direction.ASC; } Sort.Order order = new Sort.Order(direction, op2[0]); list.add(order);//每次递增一个属性 } Sort sort = new Sort(list); Pageable pageable = new PageRequest(var2.getPage(),var2.getSize(),sort); return findAll(specification,pageable); } }
阅读更多
相关文章推荐
- Spring boot data JPA 自定义JPQL语句,以及PagingAndSortingRepository接口实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询(转)
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- SpringBoot第二讲 利用Spring Data JPA实现数据库的访问(二)_分页和JpaSpecificationExecutor接口介绍
- Springboot整合JPA以及动态条件查询的实现
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 【spring data jpa】带有条件的查询后分页和不带条件查询后分页实现
- SpringData JPA实现CRUD,分页与多参数排序