【业务功能篇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> …...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
