import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;
import com.xxx.controller.logManage.LogSearchParamDTO;
import com.xxx.controller.trade.TradeParams;
/**
 * 改进方向 1:能不能 通过反射 ,只要---
 * 相关知识请自行查阅JPA Criteria查询
// 过滤条件
// 1:过滤条件会被应用到SQL语句的FROM子句中。在criteria
// 查询中,查询条件通过Predicate或Expression实例应用到CriteriaQuery对象上。
// 2:这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上
// 3:CriteriaBuilder也作为Predicate实例的工厂,通过调用CriteriaBuilder 的条件方法(
// equal,notEqual, gt, ge,lt, le,between,like等)创建Predicate对象。
// 4:复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。
 * @author 小言
 * @date 2017年11月27日
 * @time 上午10:44:53
 * @version ╮(╯▽╰)╭
 */
public class SpecificationBuilderForOperateLog {

public static <T> Specification buildSpecification(Class<T> clazz,
            final LogSearchParamDTO logSearchParamDTO) {
        return new Specification<T>() {
            @Override
            public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicate = new ArrayList<Predicate>();
                Timestamp startTime = logSearchParamDTO.getStartTime();
                Timestamp endTime = logSearchParamDTO.getEndTime();
                // 时间段
                if (startTime != null && endTime != null) {
                    predicate.add(cb.between(root.<Timestamp> get("logTime"), startTime, endTime));
                }
                // 操作日志查询栏
                String searchCondition = logSearchParamDTO.getSearchCondition();
                if (searchCondition != null && !searchCondition.equals("")) {
                    predicate.add(cb.or(cb.equal(root.<String> get("operatorName"), searchCondition),
                            cb.equal(root.<String> get("operatorId"), searchCondition)));
                }
                // 操作日志用户类型
                String operatorType = logSearchParamDTO.getOperatorType();
                System.out.println("operatorType=="+operatorType);
                if (operatorType != null ){
                    predicate.add(cb.equal(root.<String> get("operatorType"), operatorType));
                }
                Predicate[] pre = new Predicate[predicate.size()];
//              System.out.println("pre=="+predicate.toArray(pre));
                query.where(predicate.toArray(pre));
                return query.getRestriction();
            }
        };
    }
}

下面是实际开发例子:

controller层

  1. @Controller
  2. @RequestMapping(value = "/operateLog")
  3. public class BgOperateLogController {
  4.  
  5. @Autowired
  6. private BgOperateLogService bgOperateLogService;
  7.  
  8. @ResponseBody
  9. @PostMapping("/findOperateLogByCondition")
  10. public Result findOperateLogByCondition(@RequestBody LogSearchParamDTO logSearchParamDTO) {
  11. System.out.println("logSearchParamDTO="+logSearchParamDTO);
  12. Map<String, Object> result = new HashMap<>();
  13. String start = logSearchParamDTO.getStart();
  14. String end = logSearchParamDTO.getEnd();
  15. if (start != null && end == null) {
  16. return new Result(1001, "操作日志查询错误,时间参数缺少结束时间", result);
  17. }
  18. if (end != null && start == null) {
  19. return new Result(1001, "操作日志查询错误,时间参数缺少开始时间", result);
  20. }
  21. //时间
  22. long startTimeTimestamp = 0L;
  23. long endTimeTimestamp = System.currentTimeMillis();
  24. if(start != null && end != null){
  25. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  26. Date startTime;
  27. Date endTime;
  28. try {
  29. startTime = sdf.parse(start);
  30. endTime = sdf.parse(end);
  31. startTimeTimestamp = startTime.getTime();
  32. endTimeTimestamp = endTime.getTime();
  33. } catch (ParseException e) {
  34. e.printStackTrace();
  35. return new Result(1001, "操作日志查询错误,转换日期出错", result);
  36. }
  37. }
  38. String condition = logSearchParamDTO.getSearchCondition();
  39. Integer pageNumber = logSearchParamDTO.getPageNumber()-1;
  40. Integer pageSize = logSearchParamDTO.getPageSize() ;
  41. String operatorType =logSearchParamDTO.getOperatorType();
  42. Page<BgOperateLog> findByCondition = bgOperateLogService.findByCondition(new Timestamp(startTimeTimestamp),
  43. new Timestamp(endTimeTimestamp),
  44. condition,operatorType, pageNumber, pageSize);
  45. // 这些字段必须有,暂时没有做校验
  46. List<BgOperateLog> list = findByCondition.getContent();
  47. result.put("totalPages", findByCondition.getTotalPages());
  48. result.put("pageNumber", pageNumber+1);
  49. result.put("list", list);
  50. return new Result(1002, "操作日志查询成功", result);
  51. }
  52.  
  53. }

BgOperateLogController

DTO

  1. @Data
  2. public class LogSearchParamDTO {
  3. //前端传来的时间参数
  4. private String start;
  5. private String end;
  6. private Timestamp startTime;
  7. private Timestamp endTime;
  8. private String searchCondition;
  9. //操作日志查询参数
  10. //操作用户类型(0,消费者,1商家,2后台人员)
  11. private String operatorType;
  12. private Integer pageNumber;
  13. private Integer pageSize;
  14. //登陆日志查询条件
  15. public LogSearchParamDTO(Timestamp startTime, Timestamp endTime, String searchCondition) {
  16. this.startTime = startTime;
  17. this.endTime = endTime;
  18. this.searchCondition = searchCondition;
  19. }
  20. public LogSearchParamDTO() {}
  21. //操作日志查询条件
  22. public LogSearchParamDTO(Timestamp startTime, Timestamp endTime, String searchCondition, String operatorType) {
  23. this.startTime = startTime;
  24. this.endTime = endTime;
  25. this.searchCondition = searchCondition;
  26. this.operatorType = operatorType;
  27. }
  28. }

LogSearchParamDTO

service 层

  1. @Override
  2. public Page<BgOperateLog> findByCondition(Timestamp start,
  3. Timestamp end, String condition ,String operatorType,
  4. int pageNumber, int pageSize) {
  5. Sort sort = new Sort(Sort.Direction.DESC, "logTime");
  6. Pageable pageable = new PageRequest(pageNumber, pageSize, sort);
  7. LogSearchParamDTO operateLog = new LogSearchParamDTO(start, end, condition,operatorType);
  8. Page<BgOperateLog> page = bgOperateLogDao
  9. .findAll(SpecificationBuilderForOperateLog.buildSpecification(BgOperateLog.class,operateLog), pageable);
  10. return page;
  11. }

dao层

  1. import java.io.Serializable;
  2. import org.springframework.data.jpa.repository.JpaRepository;
  3. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  4. import org.springframework.stereotype.Repository;
  5. import com.xxx.entity.BgOperateLog;
  6. @Repository
  7. public interface BgOperateLogDao extends JpaRepository<BgOperateLog, Serializable>,JpaSpecificationExecutor<BgOperateLog>{}

entity层

  1. @Data
  2. @Entity
  3. public class BgOperateLog implements java.io.Serializable {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.AUTO)
  6. private Integer id;
  7. private String logText;
  8. private String operatorId;
  9. private String operatorName;
  10. private String operatorType;
  11. private String ip;
  12. @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
  13. private Timestamp logTime;
  14. }

转自:

https://blog.csdn.net/dgutliangxuan/article/details/78644464

https://blog.csdn.net/u011726984/article/details/72627706

参考:

https://www.cnblogs.com/vcmq/p/9484398.html

https://www.cnblogs.com/g-smile/p/9177841.html

Spring Data JPA 动态拼接条件的通用设计模式的更多相关文章

  1. springboot整合spring data jpa 动态查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...

  2. Spring Data JPA 复杂/多条件组合查询

    1: 编写DAO类或接口  dao类/接口 需继承 public interface JpaSpecificationExecutor<T> 接口: 如果需要分页,还可继承 public ...

  3. Spring MVC和Spring Data JPA之按条件查询和分页(kkpaper分页组件)

    推荐视频:尚硅谷Spring Data JPA视频教程,一学就会,百度一下就有, 后台代码:在DAO层继承Spring Data JPA的PagingAndSortingRepository接口实现的 ...

  4. spring data jpa实现多条件查询(分页和不分页)

    目前的spring data jpa已经帮我们干了CRUD的大部分活了,但如果有些活它干不了(CrudRepository接口中没定义),那么只能由我们自己干了.这里要说的就是在它的框架里,如何实现自 ...

  5. spring data jpa 动态查询(工具类封装)

    利用JPA的Specification<T>接口和元模型就实现动态查询了.但是这样每一个需要动态查询的地方都需要写一个这样类似的findByConditions方法,小型项目还好,大型项目 ...

  6. 序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询 多表关联查询

    查询窗口中可以设置很多查询条件 表单中输入的内容转为datagrid的load方法所需的查询条件向原请求地址再次提出新的查询,将结果显示在datagrid中 转换方法看代码注释 <td cols ...

  7. Spring Data JPA动态查询(多条件and)

    entity: @Entity @Table(name = "data_illustration") public class Test { @Id @GenericGenerat ...

  8. Spring Data JPA 复杂/多条件组合分页查询

    推荐视频: http://www.icoolxue.com/album/show/358 public Map<String, Object> getWeeklyBySearch(fina ...

  9. 【spring data jpa】带有条件的查询后分页和不带条件查询后分页实现

    一.不带有动态条件的查询 分页的实现 实例代码: controller:返回的是Page<>对象 @Controller @RequestMapping(value = "/eg ...

随机推荐

  1. numpy中与金融有关的函数

    fv函数 计算未来的价值 def fv(rate, nper, pmt, pv, when='end'): ... 参数: rate:存款/贷款每期的利率 nper:存款/贷款期数 pmt:存款/贷款 ...

  2. UvaL-7670 上下界可行费用流

    #include <iostream> #include <cstdio> #include <cstring> #include <queue> #d ...

  3. 解决 Jenkins 乱码以及命令不存在的问题

    方法一: Jenkins----系统管理----系统设置----全局属性----勾选环境变量 键 LANG 值 zh_CN.UTF-8 方法二(如果脚本用的是python): PYTHONIOENCO ...

  4. win10上使用自带的Hyper-V安装虚拟机

    Hyper-V管理器,新建虚拟机,安装了.iso系统,但启动报错,电脑上联想G40-70,都说在bios设置的security里开启硬件虚拟化选项,可我security里没有虚拟化相关选项, 后来在 ...

  5. IDA Pro - 使用IDA Pro逆向C++程序

    原文地址:Reversing C++ programs with IDA pro and Hex-rays 简介 在假期期间,我花了很多时间学习和逆向用C++写的程序.这是我第一次学习C++逆向,并且 ...

  6. 使用fastjson的parseObject方法将json字符串转换成Map 或者List

    fastjson 转换成map HashMap<String,String> map = JSON.parseObject(jsonStr,new TypeReference<Has ...

  7. Spring NamespaceHandlerResolver xml的标签加载的扩展 和 ApplicationContext

    NamespaceHandlerResolver public NamespaceHandler resolver(String namespaceUri); DefaultNamespaceHand ...

  8. Katalon Studio入门学习之三种获取元素方式

    Katalon Studio中元素属性定位有三种方式,分别是XPath.Attributes(元素).CSS(样式),KS的界面展示如右图 打开网站,按F12或进入浏览器设置->更多工具-> ...

  9. 【BZOJ3143】【Luogu P3232】 [HNOI2013]游走 概率期望,图论

    期望\(DP\)入门题目. 关键思想:无向边的转移作为有向边考虑.其他的就是直接上全期望公式.由于这个题目不是有向无环图,所以需要高斯消元搞一搞. 设每个点的期望经过次数是\(g(x)\),那么有 \ ...

  10. shell知识点(一)

    Shell1.概述Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核还是一个功能相当强大的编程语言,易编写.易调试.灵活性强2.shell解析器查看linux提供的shell ...