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

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);
}

}

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: