【业务功能篇102】springboot+mybatisPlus分页查询,统一返回封装规范
业务场景: 随着业务代码量增多,很多接口查询的分页写法各种各样,为了使项目工程代码易于维护,我们统一规范,相对没有那么复杂的接口,我们统一都在java的service实现类中,去完成分页查询的接口逻辑,减少dao层大量的分页sql,或者各式各样的分页查询写法,所以写了一些通用工具类,进行重构。
页面插件
需要引入mybatisPlus的配置类 才能生效分页功能
package com.msb.mall.product.config;import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@EnableTransactionManagement // 开启事务
@MapperScan("com.msb.mall.product.dao")
public class MybatisPlusConfig {// 旧版@Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor = new PaginationInterceptor();// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认falsepaginationInterceptor.setOverflow(true);// 设置最大单页限制数量,默认 500 条,-1 不受限制paginationInterceptor.setLimit(500);// 开启 count 的 join 优化,只针对部分 left joinpaginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));return paginationInterceptor;}// 最新版/*@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));return interceptor;}*/
}
通用分页查询类Query<T>
package com.msb.common.utils;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.msb.common.xss.SQLFilter;
import org.apache.commons.lang.StringUtils;import java.util.Map;/*** 查询参数**/
public class Query<T> {public IPage<T> getPage(Map<String, Object> params) {return this.getPage(params, null, false);}public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {//分页参数long curPage = 1;long limit = 10;if(params.get(Constant.PAGE) != null){curPage = Long.parseLong((String)params.get(Constant.PAGE));}if(params.get(Constant.LIMIT) != null){limit = Long.parseLong((String)params.get(Constant.LIMIT));}//分页对象Page<T> page = new Page<>(curPage, limit);//分页参数params.put(Constant.PAGE, page);//排序字段//防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));String order = (String)params.get(Constant.ORDER);//前端字段排序if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){if(Constant.ASC.equalsIgnoreCase(order)) {return page.addOrder(OrderItem.asc(orderField));}else {return page.addOrder(OrderItem.desc(orderField));}}//没有排序字段,则不排序if(StringUtils.isBlank(defaultOrderField)){return page;}//默认排序if(isAsc) {page.addOrder(OrderItem.asc(defaultOrderField));}else {page.addOrder(OrderItem.desc(defaultOrderField));}return page;}
}
SQL参数防攻击过滤类SQLFilter
package com.msb.common.xss;import com.msb.common.exception.RRException;
import org.apache.commons.lang.StringUtils;/*** SQL过滤**/
public class SQLFilter {/*** SQL注入过滤* @param str 待验证的字符串*/public static String sqlInject(String str){if(StringUtils.isBlank(str)){return null;}//去掉'|"|;|\字符str = StringUtils.replace(str, "'", "");str = StringUtils.replace(str, "\"", "");str = StringUtils.replace(str, ";", "");str = StringUtils.replace(str, "\\", "");//转换成小写str = str.toLowerCase();//非法字符String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"};//判断是否包含非法字符for(String keyword : keywords){if(str.indexOf(keyword) != -1){throw new RRException("包含非法字符");}}return str;}
}
自定义参数非法异常类
package com.msb.common.exception;/*** 自定义异常*/
public class RRException extends RuntimeException {private static final long serialVersionUID = 1L;private String msg;private int code = 500;public RRException(String msg) {super(msg);this.msg = msg;}public RRException(String msg, Throwable e) {super(msg, e);this.msg = msg;}public RRException(String msg, int code) {super(msg);this.msg = msg;this.code = code;}public RRException(String msg, int code, Throwable e) {super(msg, e);this.msg = msg;this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}}
相关常量类
package com.msb.common.utils;/*** 常量**/
public class Constant {/** 超级管理员ID */public static final int SUPER_ADMIN = 1;/*** 当前页码*/public static final String PAGE = "page";/*** 每页显示记录数*/public static final String LIMIT = "limit";/*** 排序字段*/public static final String ORDER_FIELD = "sidx";/*** 排序方式*/public static final String ORDER = "order";/*** 升序*/public static final String ASC = "asc";}
封装返回PageUtil分页工具类
package com.msb.common.utils;import com.baomidou.mybatisplus.core.metadata.IPage;import java.io.Serializable;
import java.util.List;/*** 分页工具类**/
public class PageUtils implements Serializable {private static final long serialVersionUID = 1L;/*** 总记录数*/private int totalCount;/*** 每页记录数*/private int pageSize;/*** 总页数*/private int totalPage;/*** 当前页数*/private int currPage;/*** 列表数据*/private List<?> list;/*** 分页* @param list 列表数据* @param totalCount 总记录数* @param pageSize 每页记录数* @param currPage 当前页数*/public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {this.list = list;this.totalCount = totalCount;this.pageSize = pageSize;this.currPage = currPage;this.totalPage = (int)Math.ceil((double)totalCount/pageSize);}/*** 分页*/public PageUtils(IPage<?> page) {this.list = page.getRecords();this.totalCount = (int)page.getTotal();this.pageSize = (int)page.getSize();this.currPage = (int)page.getCurrent();this.totalPage = (int)page.getPages();}public int getTotalCount() {return totalCount;}public void setTotalCount(int totalCount) {this.totalCount = totalCount;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public int getTotalPage() {return totalPage;}public void setTotalPage(int totalPage) {this.totalPage = totalPage;}public int getCurrPage() {return currPage;}public void setCurrPage(int currPage) {this.currPage = currPage;}public List<?> getList() {return list;}public void setList(List<?> list) {this.list = list;}}
封装返回前端响应通用类R
package com.msb.common.utils;import org.apache.http.HttpStatus;import java.util.HashMap;
import java.util.Map;/*** 返回数据**/
public class R extends HashMap<String, Object> {private static final long serialVersionUID = 1L;public R() {put("code", 0);put("msg", "success");}public static R error() {return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");}public static R error(String msg) {return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);}public static R error(int code, String msg) {R r = new R();r.put("code", code);r.put("msg", msg);return r;}public static R ok(String msg) {R r = new R();r.put("msg", msg);return r;}public static R ok(Map<String, Object> map) {R r = new R();r.putAll(map);return r;}public static R ok() {return new R();}public R put(String key, Object value) {super.put(key, value);return this;}public Integer getCode(){return (Integer) this.get("code");}public String getMessage(Integer code){return (String) this.get(code);}
}
实例:分页查询接口
controller层
@RestController
@RequestMapping("product/attrgroup")
public class AttrGroupController {@Autowiredprivate AttrGroupService attrGroupService;/*** 列表* 分页查询* 前端提交请求需要封装对应的分页数据* {* page:1, // 当前页* limit:10, // 每页显示的条数* sidx:"id", // 排序的字段* order:"asc/desc", // 排序的方式* key:"小米" // 查询的关键字* }*/@RequestMapping("/list/{catelogId}")public R list(@RequestParam Map<String, Object> params,@PathVariable("catelogId") Long catelogId){// PageUtils page = attrGroupService.queryPage(params);PageUtils page = attrGroupService.queryPage(params,catelogId);return R.ok().put("page", page);}}
service层接口
public interface AttrGroupService extends IService<AttrGroupEntity> {PageUtils queryPage(Map<String, Object> params, Long catelogId);}
service层实现类
@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {/*** 查询列表数据* 根据列表编号来查询* @param params* @param catelogId 如何catelogId为0 就不根据catelogId来查询* @return*/@Overridepublic PageUtils queryPage(Map<String, Object> params, Long catelogId) {// 获取检索的关键字String key = (String) params.get("key");QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();if(!StringUtils.isEmpty(key)){// 拼接查询的条件wrapper.and((obj)->{obj.eq("attr_group_id",key).or().like("attr_group_name",key);});}if(catelogId == 0){// 不根据catelogId来查询IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),wrapper);return new PageUtils(page);}// 根据类别编号来查询属性信息wrapper.eq("catelog_id",catelogId);IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),wrapper);return new PageUtils(page);}
}
dao层接口
@Mapper
public interface AttrGroupDao extends BaseMapper<AttrGroupEntity> {
表单实体类
@Data
@TableName("pms_attr_group")
public class AttrGroupEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 分组id*/@TableIdprivate Long attrGroupId;/*** 组名*/private String attrGroupName;/*** 排序*/private Integer sort;/*** 描述*/private String descript;/*** 组图标*/private String icon;/*** 所属分类id*/private Long catelogId;/*** 修改数据的时候记录类别信息* [2,22,225]*/@TableField(exist = false)private Long[] catelogPath;}
相关文章:
【业务功能篇102】springboot+mybatisPlus分页查询,统一返回封装规范
业务场景: 随着业务代码量增多,很多接口查询的分页写法各种各样,为了使项目工程代码易于维护,我们统一规范,相对没有那么复杂的接口,我们统一都在java的service实现类中,去完成分页查询的接口逻…...
中国手机新进程:折叠屏出海的荣耀,5G中回归的华为
最近,“华为5G回归”“自研麒麟芯片回归”的消息引爆网络。网友开心庆贺之余,也纷纷猜测,华为强势归来,哪家友商最慌? “华为的回归,让竞争充满了更多的可能性和更多的魅力”,与华为渊源颇深的…...
安装RabbitMQ的各种问题(包括已注册成windows服务后,再次重新安装,删除服务重新注册遇到的问题)
一、安装Erlang(傻瓜式安装) 安装完成之后,配置环境变量: 1.新建系统变量名为:ERLANG_HOME 变量值为erlang安装地址 2. 双击系统变量path,点击“新建”,将%ERLANG_HOME%\bin加入到path中。 …...
多线程与高并发——并发编程(6)
文章目录 六、并发集合1 ConcurrentHashMap1.1 存储结构1.2 存储操作1.2.1 put方法1.2.2 putVal方法-散列算法1.2.3 putVal方法-添加数据到数组&初始化数组1.2.4 putVal方法-添加数据到链表1.3 扩容操作1.3.1 treeifyBin方法触发扩容1.3.2 tryPresize方法-针对putAll的初始…...
Elasticsearch——Docker单机部署安装
文章目录 1 简介2 Docker安装与配置2.1 安装Docker2.2 配置Docker镜像加速器2.3 调整Docker资源限制 3 准备Elasticsearch Docker镜像3.1 下载Elasticsearch镜像3.2 自定义镜像配置3.3执行Docker Compose 4 运行Elasticsearch容器4.1 创建Elasticsearch容器4.2 修改配置文件4.3…...
基于AHP模型指标权重分析python整理
一 背景介绍 日常会有很多定量分析的场景,然而也会有一些定性分析的场景针对定性分析的场景,预测者只能通过主观判断分析能力来推断事物的性质和发展趋势然而针对个人的直觉和虽然能够有一定的协助判断效果,但是很难量化到指标做后期的复用 …...
用python实现基本数据结构【02/4】
*说明 如果需要用到这些知识却没有掌握,则会让人感到沮丧,也可能导致面试被拒。无论是花几天时间“突击”,还是利用零碎的时间持续学习,在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢?列表、字典、集…...
蓝牙Mesh专有DFU
蓝牙Mesh专有DFU Mesh专有DFU协议介绍特征DFU模式和类型角色并发传输混合设备的网络传输速率后台操作传输分区内存映射安全DFU固件IDApplication firmware IDSoftDevice firmware IDBootloader firmware ID 设备页面格式内容 Mesh专有DFU协议介绍 设备固件更新(Device Firmwar…...
浅谈综合管廊智慧运维管理平台应用研究
贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要:为提升综合管廊运维管理水平,实现管理的数字化转型,采用综合监测系统、BIMGIS 可视化系统、智能机器人巡检、结构安全监测等技术,搭建实时监控、应急管理、数据分析等多功能…...
Httpservletrequest与Httpservletresponse
目录 一、Httpservletrequest 1.1什么是Httpservletrequest 1.2Httpservletrequest中的方法 二、Httpservletresponse 1.1什么是Httpservletresponse 1.2Httpservletresponse的方法 一、Httpservletrequest 1.1什么是Httpservletrequest HttpServletRequest(…...
文件上传之图片码混淆绕过(upload的16,17关)
目录 1.upload16关 1.上传gif loadup17关(文件内容检查,图片二次渲染) 1.上传gif(同上面步骤相同) 2.条件竞争 1.upload16关 1.上传gif imagecreatefromxxxx函数把图片内容打散,,但是不会…...
Jetsonnano B01 笔记5:IIC通信
今日继续我的Jetsonnano学习之路,今日学习的是IIC通信,并尝试使用Jetson读取MPU6050陀螺仪数据。文章提供源码。文章主要是搬运的官方PDF说明,这里结合自己实际操作作笔记。 目录 IIC通信: IIC硬件连线: 安装IIC库文…...
【网络爬虫笔记】爬虫Robots协议语法详解
Robots协议是指一个被称为Robots Exclusion Protocol的协议。该协议的主要功能是向网络蜘蛛、机器人等搜索引擎爬虫提供一个标准的访问控制机制,告诉它们哪些页面可以被抓取,哪些页面不可以被抓取。本文将进行爬虫Robots协议语法详解,同时提供…...
MATLAB 2022b 中设置关闭 MATLAB 之前进行询问
在 MATLAB 2022b 中可以进行设置,在关闭 MATLAB 之前进行询问,防止意外关闭 MATLAB。如图:...
在SpringBoot框架下,接口有读个实现类,在不改变任何源码的情况下,SpringBoot怎么知道给接口注入哪个实现类的依赖呢?
在Spring Boot框架下,当一个接口有多个实现类时,Spring Boot 默认情况下不知道要注入哪个实现类的依赖。因此,你需要使用一些方法来明确告诉Spring Boot应该注入哪个实现类的依赖。 以下是一些常用的方法: 1.使用Qualifier注解&a…...
探索数据库管理的利器 - PHPMyAdmin
有一个项目,后端由博主独自负责,最近需要将项目交接给另一位同事。在项目初期,博主直接在数据库中使用工具创建了相关表格,并在完成后利用PhpMyAdmin生成了一份数据字典,供团队使用。然而,在随后的开发过程…...
大数据技术原理与应用学习笔记第1章
黄金组合访问地址:http://dblab.xmu.edu.cn/post/7553/ 1.《大数据技术原理与应用》教材 官网:http://dblab.xmu.edu.cn/post/bigdata/ 2.大数据软件安装和编程实践指南 官网林子雨编著《大数据技术原理与应用》教材配套大数据软件安装和编程实践指…...
算法从未放弃你,放弃你的只有你自己
在人生的旅程中,我们常常会遇到各种挫折和困难。有些人在面对困境时,会选择放弃,将责任归咎于命运或外部环境。然而,算法教给我们一个重要的道理:永远不要放弃 当我们遇到问题或挑战时,算法可以帮助我们找到…...
[Linux 基础] linux基础指令(1)
文章目录 1、Linux下基本指令1.ls指令2.pwd指令3.cd指令4.touch指令5.mkdir指令6.rmdir指令 && rm指令7.man指令8.cp指令9.mv指令10.cat指令11.more指令12.less指令 Linux学习笔记从今天开始不断更新了。第一篇我们从基础指令开始学起。 1、Linux下基本指令 好多人都说…...
ESP32蓝牙主从站模式:主站发送,从站接收,同时附加简单通信协议
主站发送:WXAiBj,六个字符 蓝牙模式是一个字符一个字符发送 主站和从站设置通信协议 使得六个字符一句话完整接收,同时打印出接收完成信息 硬件电路连接如下: 主从站为两个ESP32,只使用了其中的蓝牙功能 代码如下: 主站: //主机模式 #include <Arduino.h> …...
Redis布隆过滤亿级大数据
场景描述 小程序用户的openid作为最主要的业务查询字段,在做了缓存设计之后仍有非常高频的查询,通过埋点简单统计约在每日1000w次。 其中:由于有新增用户原因,导致请求的openid根本不存在MySQL数据库中,这部分统计约占…...
车联网仿真工具Veins学习1
准备条件 假如你是一个小白,先找到相关的参考资料(已根据上一篇博客安装好Veins),主要是官方文档和相关的博客,官方提供了一个example,我找到的资料如下: Frequently Asked Questions (FAQ) O…...
封闭岛屿数量 -- 二维矩阵的dfs算法
1254. 统计封闭岛屿的数目 这道题和 岛屿数量 – 二维矩阵的dfs算法 类似,区别在于不算边缘部分的岛屿,那其实很简单,把上⼀题中那些靠边的岛屿排除掉,剩下的就是「封闭岛屿」了。 关于岛屿的相似题目: 岛屿数量 –…...
C语言_指针(1)
文章目录 前言一、指针数组1.1利用指针数组模拟出二维数组 二、数组指针2.1数组名是数组首元素的地址2.2 二维数组传参2.3 一级指针传参2.4 二级指针传参 三. 函数指针四 . typedef 重命名 前言 指针数组是由指针组成的数组。它的每个元素都是一个指针,可以指向任何…...
建站系列(一)--- 网站基本常识
目录 相关系列文章前言一、因特网二、网站三、服务器四、IP五、域名六、DNS七、Hosts文件八、端口号九、URL十、静态网站十一、动态网站 相关系列文章 建站系列(一)— 网站基本常识 建站系列(二)— 域名、IP地址、URL、端口详解 …...
Codeforces Round 895 (Div. 3) A ~ F
Dashboard - Codeforces Round 895 (Div. 3) - Codeforces A 问多少次能使a 和 b相等,就是abs(a - b) / 2除c向上取整,也就是abs(a - b)除2c向上取整。 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #de…...
【前端知识】Axios——请求拦截器模板
Axios——请求拦截器模板 Axios是一个基于Promise的HTTP客户端,用于发送HTTP请求。它可以在浏览器和Node.js环境中使用,并且提供了许多强大的功能,例如拦截请求和响应、转换请求和响应数据、取消请求等。 Axios具有简单易用的API,…...
企业架构LNMP学习笔记16
基于IP的访问控制: 基于ngx_http_access_module模块,默认可使用。 语法是: deny ip 禁止IP访问 allow ip 允许IP访问 上面是允许的,下面是deny的。 老师建议写在server段中是比较合适的。 基于用户的访问控制: …...
redis实现消息队列
背景 消息队列(Message Queue)是一种常见的软件架构模式,用于在分布式系统中传递和处理异步消息。它解耦了发送消息的应用程序和接收消息的应用程序之间的直接依赖关系,使得消息的发送者和接收者可以独立地演化和扩展。 消息队列…...
JVM指令集
概述 JVM,Java Virtual Machine,Java虚拟机器,作为一台独立的机器,一般包括独立的指令集、独立的存储体系以及适合机器自身的运算方式,本章节主要是描述JVM指令的功能与作用。 JVM的每个指令的格式是【指令 操作数1操…...
大学网站建设目标/百度联盟推广
ffmpeg.exe -i F:\闪客之家\闪客之歌.mp3 -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 f:\11.flv ffmpeg -i F:\01.wmv -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 f:\test.flv 使用-ss参数 作用(time_off set the start time offset),可以从指…...
企业网上推广方式/windows优化大师免费
LeetCode 1401. 圆和矩形是否有重叠 难度 中等 给你一个以 (radius, x_center, y_center) 表示的圆和一个与坐标轴平行的矩形 (x1, y1, x2, y2),其中 (x1, y1) 是矩形左下角的坐标,(x2, y2) 是右上角的坐标。 如果圆和矩形有重叠的部分,请…...
网站建设项目的预表/快速优化系统
导读: ActiveSync应用层程序协议分析-RAPI的握手过程 转载时请注明出处和作者联系方式作者联系方式:李先静 ActiveSync与Window Mobile之间的通信协议并不复杂,在RNDISUSBNET之上运行TCP/IP,而TCP/IP之上的应用层协议包括RAPI和RR…...
未来的门户网站/线上推广引流渠道
三维在理解了如何绘制2D元素之后,我们尝试绘制3D元素。 其实多个三角形也能够成四面体,多个长方形也能够成六面体,所以绘制3D元素的时候,只要顶点数量匹配就行了 这里我们尤其注意,我把绘制之前的三个平移和三个旋转单…...
新闻网站建设的任务要求/网络营销推广方案3篇
左移运算符就是在二进制的基础上对数字进行平移。按照平移的方向和填充数字的规则分为三种:<<(左移)、>>(带符号右移)和>>>(无符号右移)。 在 移位运算时,byte、 short和char类型移位后的结果会变成int类型,对于byte、s…...