基于spring data jpa封装带有动态分页查询、动态条件求和的基础service类和基础controller类

基于spring data jpa封装带有动态分页查询、动态条件求和的基础service类和基础controller类

本文章介绍的是封装一个带有动态条件分页查询和动态条件求和基类
项目:springBoot项目
前提条件:引入spring data jpa依赖

源码地址:https://github.com/lizhongxiang12138/eurekaManage

代码结构

│  .gitignore
│  build.sh
│  demo.iml
│  dev-product.release
│  Dockerfile
│  eureka-mannage-deployment.yaml
│  eureka-mannage-service.yaml
│  HELP.md
│  mvnw
│  mvnw.cmd
│  pom.xml
│  README.md
│
├─.idea
│  │  compiler.xml
│  │  encodings.xml
│  │  misc.xml
│  │  modules.xml
│  │  uiDesigner.xml
│  │  vcs.xml
│  │  workspace.xml
│  │
│  ├─inspectionProfiles
│  │      Project_Default.xml
│  │
│  └─libraries
└─src
    ├─main
    │  ├─java
    │  │  └─com
    │  │      └─lzx
    │  │          └─demo
    │  │              │  DemoApplication.java --> 启动类
    │  │              │
    │  │              ├─annotation
    │  │              │      LzxLockDistributed.java
    │  │              │
    │  │              ├─aop
    │  │              │      MethodLockAop.java
    │  │              │
    │  │              ├─base
    │  │              │  │  ClassHelper.java
    │  │              │  │
    │  │              │  ├─bo
    │  │              │  │      ClassTypeBo.java
    │  │              │  │      ColumnConditionBO.java
    │  │              │  │
    │  │              │  ├─controller
    │  │              │  │      BaseController.java -->Controller基类
    │  │              │  │
    │  │              │  └─service
    │  │              │      │  BaseService.java --> Service基类接口
    │  │              │      │
    │  │              │      └─impl
    │  │              │              BaseServiceImpl.java --> Service基类实现
    │  │              │
    │  │              ├─config
    │  │              │      RepositoryConfig.java
    │  │              │
    │  │              ├─configuration
    │  │              │      ActuatorWebSecurityConfigurationAdapter.java
    │  │              │      RedisLockConfiguration.java
    │  │              │      Swagger.java
    │  │              │      ThreadPoolConfig.java
    │  │              │
    │  │              ├─controller
    │  │              │      RedisLockTestController.java
    │  │              │      StudentController.java  -- >基类测试用的controller
    │  │              │      TestController.java
    │  │              │
    │  │              ├─Dao
    │  │              │      StudentDao.java --> 基类测试用的dao
    │  │              │
    │  │              ├─dto
    │  │              │      ApplicationDTO.java
    │  │              │      ApplicationsDTO.java
    │  │              │      DataCenterInfoDTO.java
    │  │              │      InstanceDTO.java
    │  │              │      KafkaMessDTO.java
    │  │              │      LeaseInfoDTO.java
    │  │              │      MetadataDTO.java
    │  │              │      PageableDTO.java
    │  │              │      PageDataDTO.java
    │  │              │      ProductProtocolDTO.java
    │  │              │
    │  │              ├─entity
    │  │              │      Student.java --> 基类测试用的实体
    │  │              │
    │  │              ├─feign
    │  │              │      SelfFeign.java
    │  │              │      SrdFeign.java
    │  │              │
    │  │              └─service
    │  │                  │  KafkaService.java
    │  │                  │  StudentService.java --> 基类测试用的service接口
    │  │                  │
    │  │                  └─impl
    │  │                          KafkaServiceImpl.java
    │  │                          StudentServiceImpl.java --> 基类测试用的service实现
    │  │
    │  └─resources
    │      │  application.yml
    │      │  bootstrap.yml
    │      │
    │      ├─static
    │      │      apps.html
    │      │      testSendToKafka-ui.html
    │      │
    │      └─templates
    └─test
        └─java
            └─com
                └─lzx
                    └─demo
                        │  DemoApplicationTests.java
                        │
                        └─service
                            └─impl
                                    KafkaServiceImplTest.java

添加依赖

        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            mysql
            mysql-connector-java
            5.1.42
        
        
            org.springframework.boot
            spring-boot-starter-data-rest
        

数据库配置

server:
  port: ${server-port}

eureka:
  client:
    fetch-registry: true
    register-with-eureka: ${register-with-eureka}     # 是否注册到eureka
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  instance:
    prefer-ip-address: false
    hostname: ${instance-hostname}


spring:
  kafka:
    bootstrap-servers: 39.100.73.134:9092     #Kafka服务端地址
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
  profiles:
    active: dev
  redis:
    port: 6379
    host: 39.100.132.241
    password: 123456


  ######################################################
  #   数据库连接相关配置
  ######################################################
  datasource:
    url: jdbc:mysql://39.100.132.241:3306/eureka_manage?autoReconnect=true&characterEncoding=utf-8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5Dialect



创建一个实体模型,方便后续测试

package com.lzx.demo.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.math.BigDecimal;

/**
 * 描述: 学生类
 *
 * @Auther: lzx
 * @Date: 2019/7/11 15:39
 */
@Entity(name = "STUDENT")
@Getter
@Setter
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class Student {

    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @Column(name = "ID",length = 32)
    private String id;

    /**
     * 名称
     */
    @Column(name = "NAME",length = 100)
    private String name;

    /**
     * 性别
     */
    @Column(name = "GENDER",length = 8)
    @Enumerated(EnumType.STRING)
    private Gender gender;
    @Getter
    @AllArgsConstructor
    public enum Gender{
        WOMAN("女"),
        MAN("男");
        private String code;
    }

    /**
     * 分数
     */
    @Column(name = "SCORE",precision = 10,scale = 5)
    private BigDecimal score;
}

创建实体模型DAO接口

package com.lzx.demo.Dao;

import com.lzx.demo.entity.Student;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.Repository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

/**
 * 描述: 学生类dao接口
 *
 * @Auther: lzx
 * @Date: 2019/7/11 15:52
 */
@RepositoryRestResource(path = "student")
public interface StudentDao extends Repository,JpaSpecificationExecutor {
}

创建BaseService和BaseServiceImpl

定义BaseService接口

package com.lzx.demo.base.service;

import org.springframework.data.domain.Page;

import java.util.Map;

/**
 * 描述:BaseService
 *
 * @Auther: lzx
 * @Date: 2019/7/11 16:10
 */
public interface BaseService {

    /**
     * 根据条件分页查询,条件拼接方式为 and
     * 条件拼接方式  xx字段_xx操作
     * @param params
     * @return
     */
    Page findAllPageByParams(Map params);

    /**
     * 求和数据
     * 条件同上(分页条件查询) 注意~!!! 不需要分页属性,但是要添加统计的条件
     * 求和统计条件  xxx字段_sum = xx类型(支持BigDecimal 和 Long)
     *
     * @param params 参数
     * @return 查询条件
     */
    Map getSumByParams(Map params) throws Exception;
}

实现BaseService(BaseServiceImpl)

package com.lzx.demo.base.service.impl;

import com.lzx.demo.base.ClassHelper;
import com.lzx.demo.base.bo.ClassTypeBo;
import com.lzx.demo.base.bo.ColumnConditionBO;
import com.lzx.demo.base.service.BaseService;
import lombok.extern.slf4j.Slf4j;
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.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 描述: 基础service实现
 *
 * @Auther: lzx
 * @Date: 2019/7/11 16:14
 */
@Slf4j
public class BaseServiceImpl implements BaseService {

    /**
     * 实现的dao
     * 需要在子类中具体注入
     */
    protected JpaSpecificationExecutor dao;

    /**
     * 实体管理类,使用统计求和查询时用到
     */
    @PersistenceContext
    private EntityManager em;

    /**
     * 类型
     */
    private Class clazz;

    /**
     * 根据条件分页查询,条件拼接方式为 and
     * 条件拼接方式  xx字段_xx操作,比如等于查询 xxx_eq=xxx
     * 具体操作符查看 ColumnConditionBO
     * @param params
     * @return
     */
    @Override
    public Page findAllPageByParams(Map params){
        Specification specification = this.getSpecification(params);
        return dao.findAll(specification, getPageable(params));
    }

    /**
     * 求和数据
     * 条件同上(分页条件查询) 注意~!!! 不需要分页属性,但是要添加统计的条件
     * 求和统计条件  xxx字段_sum = xx类型(支持BigDecimal 和 Long)
     *
     * @param params 参数
     * @return 查询条件
     */
    public Map getSumByParams(Map params) throws Exception {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery query = cb.createTupleQuery();
        clazz = (Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Root root = query.from(clazz);

        List predicateListNew = getPredicateList(params,cb,root);

        Predicate[] pred = new Predicate[predicateListNew.size()];
        pred = predicateListNew.toArray(pred);


        query.where(pred);
        Set keySet = params.keySet();
        List> selections = new ArrayList>();
        Iterator iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            if (key.contains("_sum")) {
                if ("BigDecimal".equals(params.get(key))) {
                    selections.add(cb.sum(root.get(key.split("_")[0]).as(BigDecimal.class)));
                } else {
                    selections.add(cb.sum(root.get(key.split("_")[0]).as(Long.class)));
                }
            }
        }
        query.multiselect(selections);
        TypedQuery q = em.createQuery(query);
        List result = q.getResultList();
        Tuple tuple = result.get(0);
        Map param = new HashMap<>();
        int i = 0;
        Iterator resultParam = keySet.iterator();
        while (resultParam.hasNext()) {
            String key = resultParam.next();
            if (key.contains("_sum")) {
                param.put(key, tuple.get(i));
                i++;
            }
        }
        return param;
    }

    /**
     * 获取查询所需要的参数
     * @param params
     * @return
     */
    private Specification getSpecification(Map params) {
        return  ((root, query, criteriaBuilder) -> {
            List predicateList = this.getPredicateList(params,criteriaBuilder,root);
            Predicate[] p = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(p));
        });
    }


    /**
     * 获取分页属性
     * @param map
     * @return
     */
    private Pageable getPageable(Map map) {
        int page;
        int size;
        try {
            page = Integer.parseInt(map.get("page")) - 1;
            size = Integer.parseInt(map.get("size"));
        } catch (Exception e) {
            log.error(e.getMessage());
            page = 0;
            size = 20;
        }
        String sortString = map.get("sort");
        if (null == sortString) {
            return PageRequest.of(page, size);
        } else {
            List orderList=new ArrayList<>();
            String[] columnAndDirections=sortString.split(";");
            for(int i=0;i createPredicateList(){
        return new ArrayList();
    }

    /**
     * 获取predicateList
     * @param map
     * @return
     */
    private List getPredicateList(Map map, CriteriaBuilder cb, Root root){
        List predicateList = new ArrayList<>();
        map.forEach((k, v) -> {
            try {
                ColumnConditionBO columnConditionBO = ColumnConditionBO.parse(k);
                Predicate predicate=this.getPredicate(columnConditionBO, v, cb, root);
                if(predicate==null){
                    log.warn(k+"查询条件错误");
                }else{
                    predicateList.add(predicate);
                }

            } catch (Exception e) {
                log.error(e.getMessage());
            }
        });
        return predicateList;
    }

    /**
     * 获取查询
     *
     * @param columnConditionBO 字段、条件业务类
     * @param value             查询值
     * @param criteriaBuilder   cb
     * @param root              root
     * @return 查询条件
     */
    private Predicate getPredicate(ColumnConditionBO columnConditionBO, String value, CriteriaBuilder criteriaBuilder, Root root) throws NoSuchFieldException {
        //获取查询字段的类型,fieldClass为查询类中字段的类型,classType为根据类型定义的枚举类
        clazz = (Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        while (clazz!=null){
            try{
                //对于子类无法获取父类的私有属性,需要递归向上获取父类的私有属性
                Field field = ClassHelper.getDeclaredField(clazz, columnConditionBO.getColumn());
                Class fieldClass = field.getType();
                //判断fieldClass是否是枚举类
                if (!fieldClass.isEnum()) {
                    return basicPredicate(columnConditionBO, value, criteriaBuilder, root, fieldClass);
                } else {
                    return enumPredicate(columnConditionBO, value, criteriaBuilder, root, fieldClass.getEnumConstants());
                }
            }catch (Exception e){
                log.error(e.getMessage());
                clazz=clazz.getSuperclass();
            }
        }
        String noSuchFieldException="根据查询参数获取类中的域失败";
        log.warn(noSuchFieldException);
        throw new NoSuchFieldException(noSuchFieldException);
    }

    /**
     * 基础类predicate生成方法
     *
     * @param columnConditionBO 参数条件
     * @param value             查询条件值
     * @param criteriaBuilder   构建起
     * @param root              root
     * @param fieldClass        fieldClass
     * @return predicate
     */
    private Predicate basicPredicate(ColumnConditionBO columnConditionBO, String value, CriteriaBuilder criteriaBuilder, Root root, Class fieldClass) {
        ClassTypeBo classType = ClassTypeBo.valueOf(fieldClass.getSimpleName());
        switch (columnConditionBO.getCondition()) {
            case lk: {
                return criteriaBuilder.like(root.get(columnConditionBO.getColumn()), value);
            }case sw: {
                return criteriaBuilder.like(root.get(columnConditionBO.getColumn()), value + "%");
            }case ew: {
                return criteriaBuilder.like(root.get(columnConditionBO.getColumn()), "%" + value);
            }case containing: {
                return criteriaBuilder.like(root.get(columnConditionBO.getColumn()), "%" + value + "%");
            }case eq: {
                return criteriaBuilder.equal(root.get(columnConditionBO.getColumn()), value);
            }case not:{
                return criteriaBuilder.notEqual(root.get(columnConditionBO.getColumn()), value);
            }case isNull:{
                return criteriaBuilder.isNull(root.get(columnConditionBO.getColumn()));
            }case isNotNull:{
                return criteriaBuilder.isNotNull(root.get(columnConditionBO.getColumn()));
            }case between: {
                String[] minAndMax = value.split(",");
                switch (classType) {
                    case LocalDateTime: {
                        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
                        return criteriaBuilder.between(root.get(columnConditionBO.getColumn()), LocalDateTime.parse(minAndMax[0], dateTimeFormatter), LocalDateTime.parse(minAndMax[1], dateTimeFormatter));
                    }case String: {
                        return criteriaBuilder.between(root.get(columnConditionBO.getColumn()), minAndMax[0], minAndMax[1]);
                    }case Integer: {
                        return criteriaBuilder.between(root.get(columnConditionBO.getColumn()), Integer.parseInt(minAndMax[0]), Integer.parseInt(minAndMax[1]));
                    }case Long: {
                        return criteriaBuilder.between(root.get(columnConditionBO.getColumn()), Long.parseLong(minAndMax[0]), Long.parseLong(minAndMax[1]));
                    }case BigDecimal: {
                        return criteriaBuilder.between(root.get(columnConditionBO.getColumn()), new BigDecimal(minAndMax[0]), new BigDecimal(minAndMax[1]));
                    }case Date:{
                        SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                        try {
                            return criteriaBuilder.between(root.get(columnConditionBO.getColumn()), dateTimeFormatter.parse(minAndMax[0]),dateTimeFormatter.parse(minAndMax[1]));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }default:
                        return null;
                }
            }case ge:{
                switch (classType){
                    case Date:{
                        SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                        try {
                            return criteriaBuilder.greaterThanOrEqualTo(root.get(columnConditionBO.getColumn()), dateTimeFormatter.parse(value));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }default:{
                        return criteriaBuilder.greaterThanOrEqualTo(root.get(columnConditionBO.getColumn()), value);
                    }
                }
            }case gt:{
                switch (classType){
                    case Date:{
                        SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                        try {
                            return criteriaBuilder.greaterThan(root.get(columnConditionBO.getColumn()), dateTimeFormatter.parse(value));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }default:{
                        return criteriaBuilder.greaterThanOrEqualTo(root.get(columnConditionBO.getColumn()), value);
                    }
                }
            }case le:{
                switch (classType){
                    case Date:{
                        SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                        try {
                            return criteriaBuilder.lessThanOrEqualTo(root.get(columnConditionBO.getColumn()), dateTimeFormatter.parse(value));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }default:{
                        return criteriaBuilder.greaterThanOrEqualTo(root.get(columnConditionBO.getColumn()), value);
                    }
                }
            }case lt:{
                switch (classType){
                    case Date:{
                        SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                        try {
                            return criteriaBuilder.lessThan(root.get(columnConditionBO.getColumn()), dateTimeFormatter.parse(value));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }default:{
                        return criteriaBuilder.greaterThanOrEqualTo(root.get(columnConditionBO.getColumn()), value);
                    }
                }
            }case in: {
                String[] inValues = value.split(",");
                List stringList = Arrays.asList(inValues);
                switch (classType) {
                    case LocalDateTime: {
                        CriteriaBuilder.In in = criteriaBuilder.in(root.get(columnConditionBO.getColumn()));
                        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
                        stringList.forEach(s -> in.value(LocalDateTime.parse(s, dateTimeFormatter)));
                        return in;
                    }case String: {
                        CriteriaBuilder.In in = criteriaBuilder.in(root.get(columnConditionBO.getColumn()));
                        stringList.forEach(in::value);
                        return in;
                    }case Long: {
                        CriteriaBuilder.In in = criteriaBuilder.in(root.get(columnConditionBO.getColumn()));
                        stringList.forEach(s -> in.value(Long.parseLong(s)));
                        return in;
                    }case BigDecimal: {
                        CriteriaBuilder.In in = criteriaBuilder.in(root.get(columnConditionBO.getColumn()));
                        stringList.forEach(s -> in.value(new BigDecimal(s)));
                        return in;
                    }case Integer: {
                        CriteriaBuilder.In in = criteriaBuilder.in(root.get(columnConditionBO.getColumn()));
                        stringList.forEach(s -> in.value(Integer.parseInt(s)));
                        return in;
                    }default: {
                        return null;
                    }
                }
            }default: {
                return null;
            }
        }
    }

    /**
     * enum类predicate生成方法
     *
     * @param columnConditionBO 参数条件
     * @param value             查询值
     * @param criteriaBuilder   构建起
     * @param root              root
     * @param ys                ys
     * @return predicate
     */
    private  Predicate enumPredicate(ColumnConditionBO columnConditionBO, String value, CriteriaBuilder criteriaBuilder, Root root, Y[] ys) {
        //枚举类型处理
        CriteriaBuilder.In in = criteriaBuilder.in(root.get(columnConditionBO.getColumn()));
        Arrays.asList(value.split(",")).forEach(s -> Arrays.asList(ys).forEach(f -> {
            if (f.toString().equals(s)) {
                in.value(f);
            }
        }));
        return in;
    }

}

创建BaseController

package com.lzx.demo.base.controller;

import com.lzx.demo.base.service.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

/**
 * 描述: BaseController
 *
 * @Auther: lzx
 * @Date: 2019/7/11 17:03
 */
@Slf4j
public class BaseController {

    /**
     * 需要在子类中具体注入
     */
    protected BaseService baseService;

    /**
     * 根据条件分页查询,条件拼接方式为 and
     * 条件拼接方式  xx字段_xx操作
     * @param parameters
     * @return
     */
    @GetMapping("/findAllPageByParams")
    public Page findAllPageByParams(@RequestParam Map parameters) {
        return baseService.findAllPageByParams(parameters);
    }

    /**
     * 求和数据
     * 条件同上(分页条件查询) 注意~!!! 不需要分页属性,但是要添加统计的条件
     * 求和统计条件  xxx字段_sum = xx类型(支持BigDecimal 和 Long)
     *
     * @param params 参数
     * @return 查询条件
     */
    @GetMapping("/getSumByParams")
    public Map getSumByParams(@RequestParam Map params) throws Exception {
        return baseService.getSumByParams(params);
    }

}

类助手

package com.lzx.demo.base;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;

/**
 * 描述: 类助手
 *
 * @Auther: lzx
 * @Date: 2019/7/11 16:31
 */
@Slf4j
public class ClassHelper {

    /**
     * 循环向上转型, 获取对象的 DeclaredField
     * @param clazz : 子类对象类型
     * @param fieldName : 父类中的属性名
     * @return 父类中的属性对象
     */

    public static Field getDeclaredField(Class clazz, String fieldName){
        Field field = null ;

        for(; clazz != Object.class ; clazz = clazz.getSuperclass()) {
            try {
                field = clazz.getDeclaredField(fieldName) ;
                return field ;
            } catch (Exception e) {
                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
                //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了

            }
        }

        return null;
    }

}

数据类型描述

package com.lzx.demo.base.bo;

/**
 * 描述: 数据类型描述
 *
 * @Auther: lzx
 * @Date: 2019/7/11 16:34
 */
public enum  ClassTypeBo {
    /**
     * 字符串
     */
    String,
    /**
     * 整形
     */
    Integer,
    /**
     * 长整形
     */
    Long,
    /**
     * 时间
     */
    LocalDateTime,
    /**
     * bigDecimal
     */
    BigDecimal,
    /**
     * bool类型
     */
    Boolean,
    /**
     * 时间类型
     */
    Date
}

查询操作BO

package com.lzx.demo.base.bo;

import lombok.Getter;
import lombok.Setter;

/**
 * 描述:查询操作BO
 *
 * @Auther: lzx
 * @Date: 2019/7/11 16:25
 */
@Getter
@Setter
public class ColumnConditionBO {
    /**
     * 查询字段
     */
    private String column;
    /**
     * 查询条件
     */
    private Condition condition;

    public enum Condition{
        /**
         * 等于
         */
        eq,
        /**
         * like
         */
        lk,
        /**
         * start with
         * xxxxx%
         */
        sw,
        /**
         * end with
         * %xxxx
         */
        ew,
        /**
         * containing
         * %xxxxxx%
         */
        containing,
        /**
         * between
         */
        between,
        /**
         * in
         */
        in,
        /**
         * greater equal
         */
        ge,
        /**
         * great than
         */
        gt,
        /**
         * less equal
         */
        le,
        /**
         * less than
         */
        lt,
        /**
         * isNull
         */
        isNull,
        /**
         * isNotNull
         */
        isNotNull,
        /**
         * 不等于
         */
        not
    }
    public static ColumnConditionBO parse(String s){
        ColumnConditionBO columnConditionBO=new ColumnConditionBO();
        String[] strings=s.split("_");
        columnConditionBO.setColumn(strings[0]);
        columnConditionBO.setCondition(Condition.valueOf(strings[1]));
        return columnConditionBO;
    }
}

使用

service使用

接口继承BaseService

package com.lzx.demo.service;

import com.lzx.demo.base.service.BaseService;
import com.lzx.demo.entity.Student;

/**
 * 描述: 学生类service接口
 *
 * @Auther: lzx
 * @Date: 2019/7/11 17:08
 */
public interface StudentService extends BaseService {
}

实现类继承BaseServiceImpl

package com.lzx.demo.service.impl;

import com.lzx.demo.Dao.StudentDao;
import com.lzx.demo.base.service.impl.BaseServiceImpl;
import com.lzx.demo.entity.Student;
import com.lzx.demo.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.List;

/**
 * 描述:
 *
 * @Auther: lzx
 * @Date: 2019/7/11 17:09
 */
@Service
@Slf4j
public class StudentServiceImpl extends BaseServiceImpl implements StudentService {

    private StudentDao studentDao;

    public StudentServiceImpl(StudentDao studentDao) {
        /*
            !!!!!!!!!!!!!!!!!!!!重点:
            这个时必须的   ·······~~~~~~~~注意哦
         */
        this.dao = studentDao;
        this.studentDao = studentDao;
    }

    /**
     * 扩展基类中没有的查询条件自己的查询条件
     * @return
     */
    @Override
    public List createPredicateList() {
        return super.createPredicateList();
    }
}

controller使用

package com.lzx.demo.controller;

import com.lzx.demo.base.controller.BaseController;
import com.lzx.demo.entity.Student;
import com.lzx.demo.service.StudentService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 描述: 学生api
 *
 * @Auther: lzx
 * @Date: 2019/7/11 17:14
 */
@RestController
@RequestMapping("/student")
public class StudentController extends BaseController {

    private StudentService studentService;

    public StudentController(StudentService studentService) {
         /*
            !!!!!!!!!!!!!!!!!!!!重点:
            这个时必须的   ·······~~~~~~~~注意哦
         */
        this.baseService = studentService;
        this.studentService = studentService;
    }
}

最后看效果,启动项目

使用postman调用接口

分页的条件查询
基于spring data jpa封装带有动态分页查询、动态条件求和的基础service类和基础controller类_第1张图片
根据条件求和查询
基于spring data jpa封装带有动态分页查询、动态条件求和的基础service类和基础controller类_第2张图片

你可能感兴趣的:(java后端)