MyBatis Plus实现动态字段排序

news/2024/5/3 5:46:07/文章来源:https://blog.csdn.net/heyl163_/article/details/127608627

利用周末时间,对已有的项目进行了升级,原来使用的是tkmybatis,改为mybatis plus。但是由于修改了返回数据的格式,前端页面字段排序失效了,需要刷新表格才会排序。页面效果如下

easyui的数据表格datagrid支持多字段排序,以及可以控制是否通过服务器排序,核心代码如下。

role_list.html文件:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>角色列表</title><link rel="stylesheet" href="/css/themes/icon.css"/><link rel="stylesheet" href="/css/themes/default/easyui.css" /></head><body>       <table id="role_list"></table><script src="/js/public/public.js"></script><script src="/js/public/jquery.min.js"></script><script src="/js/public/jquery.easyui.min.js"></script><script src="/js/public/easyui-lang-zh_CN.js"></script><script src="/js/role_account/role_list.js"></script></body>
</html>

role_list.js文件:

$(document).ready(function() {// 角色数据表格$("#role_list").datagrid({url: '/role_account/selectByPage',method: 'post',striped: true,multiSort: true,fitColumns: true,remoteSort: true,singleSelect: true,height: table_height,pagination: true,pageList: pageList,pageSize: pageList[0],loadFilter: function(result){if (result.code === 200){return result.data;} else {return null;}},toolbar: [{iconCls: 'icon-add',text: '添加',handler: function() {handleAdd();}}, '-', {iconCls: 'icon-edit',text: '修改',handler: function() {handleUpdate();}}],columns: [[{field: 'id', title: '角色ID', align:"center", width:100, sortable: true},{field: 'name', title: '角色名', align:"center", width:120},{field: 'modelingId', title: '角色造型', align:"center", width: 80, formatter: function(value, rowData, rowIndex) {$.get("/role_modeling/selectNameAndImageById", {id: value}, function(result) {$("#modeling_" + rowIndex).attr("src", result.image).attr("title", result.name).width(size);});return "<img id='modeling_" + rowIndex + "' />";}},{field: 'grade', title: '等级', align: "center", sortable: true, width: 40, formatter: function(value) {let group; // 组别if(value >= 0 && value <= 69) { // [0, 69]精锐组group = "精锐组";} else if(value >= 70 && value <= 89) { // [70, 89]勇武组group = "勇武组";} else if(value >= 90) { // [90, 115]神威组group = "神威组";} else { // [-∞, 0) ∪ (115, +∞)group = "等级不合法";}return "<span title='" + group + "'>" + value+ "级</span>";}},{field: 'score', title: '人物评分', align:"center", sortable: true, width: 50},{field: 'schoolId', title: '门派', align:"center", width: 80, formatter: function(value, rowData, rowIndex) {$.get("/school/selectNameAndIconById", {id: value}, function(result) {$("#school_" + rowIndex).attr("src", result.icon).attr("title", result.name).width(size);});return "<img id='school_" + rowIndex + "' />";}},{field: 'jinbi', title: '金币', align:"center", sortable: true, width: 50},{field: 'accountId', title: '账号', align:"center", width:200, formatter: function(value, rowData, rowIndex) {$.get("/account/selectAccountById", {id: value}, function(response) {$("#account_" + rowIndex).html(response.data);});return "<div id='account_" + rowIndex + "'></div>";}},{field: "lastUpdateTime", title: "最后一次修改", align: "center", width:125, sortable: true},{field: 'right', title: '操作', align:"center", formatter: function(value, rowData, rowIndex) {let link = '<a href="javascript:;" ' + 'onclick="handleDelete(' + rowData.id + ')">'+ '<img title="删除" src="/css/themes/icons/delete.png" /></a>';return link;}}]]});});

其中multiSort设置为true表示允许多字段排序,remoteSort表示是否从服务器排序,设置为true,我们接下来在后台接口处理字段排序。

以上是easyui官网的截图,当多字段排序时,传递给后台的参数中通过逗号拼接。例如:通过评分score升序和等级grade降序排序时,后台接收到的参数为:

{

        "sort": "score,grade"

        "order": "asc,desc"

}

controller代码:

@RestController
@RequestMapping(path = "/role_account", produces="application/json; charset=utf-8")
public class RoleAccountController {/*** 分页条件查询角色列表* @param pagerDTO 角色分页查询条件* @return JsonPage<RoleAccount>*/@RequestMapping(path = "/selectByPage", method = RequestMethod.POST)public JsonResult<PageResult<RoleAccount>> selectByPage(RoleAccountPagerDTO pagerDTO) {return service.selectByPage(pagerDTO);}
}

service代码:

@Slf4j
@Service
public class RoleAccountServiceImpl implements IRoleAccountService {@Overridepublic JsonResult<PageResult<RoleAccount>> selectByPage(RoleAccountPagerDTO pagerDTO) {Page<RoleAccount> page = new Page<>(pagerDTO.getPage(), pagerDTO.getRows());QueryWrapper<RoleAccount> wrapper = new QueryWrapper<>();wrapper.eq(!StringUtils.isEmpty(pagerDTO.getId()), "id", pagerDTO.getId());wrapper.like(!StringUtils.isEmpty(pagerDTO.getName()), "name", pagerDTO.getName());wrapper.eq(pagerDTO.getSchoolId() != null, "school_id", pagerDTO.getSchoolId());wrapper.eq(pagerDTO.getModelingId() != null, "modeling_id", pagerDTO.getModelingId());wrapper.eq(!StringUtils.isEmpty(pagerDTO.getAccountId()), "account_id", pagerDTO.getAccountId());// 得到order by语句String statement = BasePage.getOrderByStatement(pagerDTO);log.info("得到的order by语句:{}", statement.isEmpty() ? "空" : statement);wrapper.last(statement);Page<RoleAccount> result = mapper.selectPage(page, wrapper);return JsonResult.restPage(result);}
}

mapper代码:

@Repository
public interface RoleAccountMapper extends BaseMapper<RoleAccount> {}

RoleAccount.java代码:

@Data
public class RoleAccount {@TableId("id")private String id;/*** 角色名*/private String name;/*** 等级*/private Integer grade;/*** 人物评分*/private Integer score;/*** 金币*/private Integer jinbi;/*** 账号id*/private String accountId;/*** 门派id*/private Integer schoolId;/*** 服务器id*/private Integer serverId;/*** 角色造型id*/private Integer modelingId;/*** 账号创建时间*/@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private LocalDateTime birthday;/*** 最后一次修改时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private LocalDateTime lastUpdateTime;
}

RoleAccountPagerDTO.java:

@Data
@EqualsAndHashCode(callSuper = true)
public class RoleAccountPagerDTO extends BasePage {/*** 角色id*/private String id;/*** 角色名*/private String name;/*** 等级*/private Integer grade;/*** 账号id*/private String accountId;/*** 门派id*/private Integer schoolId;/*** 角色造型id*/private Integer modelingId;
}

BasePage.java代码:

@Data
public class BasePage {/*** 页数*/private Integer page;/*** 每页记录数*/private Integer rows;/*** 排序字段*/private String sort;/*** 排序方式:asc/desc*/private String order;/*** 根据查询条件拼接得到order by语句* @param basePage 分页查询条件* @return String*/public static String getStatement(BasePage basePage) {String sort;String[] sortArray = {};String[] orderArray = {};String order = basePage.getOrder();String sortColumn = basePage.getSort();StringBuilder statement = new StringBuilder();// 多字段排序if (StringUtils.isNotEmpty(sortColumn)) {// 驼峰命名转为下划线sort = StringUtils.toLowerCase(sortColumn);if (sort.contains(",")) {sortArray = sort.split(",");}} else {return "";}if (StringUtils.isNotEmpty(order)) {if (order.contains(",")) {orderArray = order.split(",");}} else {return "";}if (sortArray.length > 0 && orderArray.length > 0) {int length = sortArray.length;for (int i = 0; i < length; i++) {statement.append(sortArray[i]);statement.append(" ");statement.append(orderArray[i]);if (i < length - 1 ) {statement.append(", ");}}} else {// " #{sort} #{order}“statement.append(sort);statement.append(" ");statement.append(order);}return statement.toString();}/*** 根据查询条件拼接得到order by语句* @param basePage 分页查询条件* @return String*/public static String getOrderByStatement(BasePage basePage) {String statement = getStatement(basePage);// 多字段排序if (StringUtils.isNotEmpty(statement)) {return " order by " + statement;} else {return statement;}}}

因为排序的字段名是驼峰命名,需要转为小写字母+下划线命名,否则sql语句会报错,找不到对应字段。转换的方法抽象到了StringUtils工具类中,代码如下。

public class StringUtils {/*** 判断字符串是否为null或""* 符串为""或null返回true,否则返回false* @param str 要判断的字符串* @return boolean*/public static boolean isEmpty(String str) {return str == null || str.isEmpty();}/*** 判断字符串是否为""或null* 符串为""或null返回false,否则返回true* @param str 要判断的字符串* @return boolean*/public static boolean isNotEmpty(String str) {return !isEmpty(str);}/*** 判断字符串是否为null或""* 符串为""或null返回true,否则返回false* @param str 要判断的字符串* @return boolean*/public static boolean isNullOrEmpty(String str) {return str == null || str.isEmpty();}/*** 检查字符串是否包含空白字符* 如果不包含空格返回true,否则返回false* @param str 需要比较的字符串* @return boolean*/public boolean check(String str) {// 去除空白字符后字符串的长度int realLength = str.replaceAll("\\s", "").length();int originalLength = str.length(); // 字符串原来的长度return realLength == originalLength;}/*** 根据当前时间生成UUID* @return String*/public static String uuid() {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");LocalDateTime localDate = LocalDateTime.now();return localDate.format(formatter);}/*** 通过文件名获取文件类型* @param fileName 文件名*/public static String getFileType(String fileName) {// 得到文件名中最后一次出现"."的位置int index = fileName.lastIndexOf('.');return fileName.substring(index);}/*** 获取文件名* @param file MultipartFile对象* @return String 由当前时间生成的新文件名*/public static String getFileName(MultipartFile file) {// 得到上传文件的原始文件名String filename = file.getOriginalFilename();// 判断文件名是否为空if (isNullOrEmpty(filename)) {throw new RuntimeException("获取文件名失败!");}// 返回uuid.文件类型,如:20220618131456.jpgreturn uuid() + getFileType(filename);}/*** 功能:驼峰命名转下划线命名* 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写* @param str 待转换的字符串* @return String*/public static String toLowerCase(String str) {str = str.replaceAll("([a-z])([A-Z])", "$1_$2");return str.toLowerCase();}/*** 功能:下划线命名转驼峰命名* 将下划线替换为空格,将字符串根据空格分割成数组,再将每个单词首字母大写* @param str 待转换的字符串* @return String*/private static String toUpperCase(String str) {StringBuilder under= new StringBuilder();str = str.toLowerCase().replace("_", " ");String[] array = str.split(" ");for (String s : array) {String letter = s.substring(0, 1).toUpperCase() + s.substring(1);under.append(letter);}return under.toString();}}

好了,本章就分享那么多了,感谢您的阅读~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_410059.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

商用车进入回暖周期,哪些供应商在领跑「主动安全」前装赛道

由于受到经济周期性影响&#xff0c;去年开始商用车市场出现一波下行行情。 中国汽车工业协会发布数据显示&#xff0c;2022年1-9月&#xff0c;商用车产销分别完成242.6万辆和248.4万辆&#xff0c;同比下降32.6%和34.2%&#xff0c;降幅较1-8月收窄1.5个百分点和2个百分点&a…

ZAB协议

1、定义 ZAB 协议全称&#xff1a;Zookeeper Atomic Broadcast&#xff08;Zookeeper 原子广播协议&#xff09;。 ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持 崩溃恢复 和 原子广播 协议&#xff0c;基于该协议&#xff0c;Zookeeper 实现了一种 主备模式 的…

什么是行内元素的盒模型

目录 行内元素的盒模型 display 可选值&#xff1a; visibility 可选值&#xff1a; 行内元素的盒模型 行内元素不支持设置宽度和高度 但是这并不是说明行内元素没有内容区 而是通过width和height不能改变内容区的大小 行内元素的内容区是由他里面的内容决定的&#xff0…

【视觉基础篇】14 # 如何使用片元着色器进行几何造型?

说明 【跟月影学可视化】学习笔记。 如何用片元着色器控制局部颜色&#xff1f; 把图片绘制为纯黑色&#xff1a; const fragment #ifdef GL_ESprecision highp float;#endifvarying vec2 vUv;void main() {gl_FragColor vec4(0, 0, 0, 1);} ;根据纹理坐标值来绘制&#…

工地ai智能视频监控系统

工地ai智能视频监控系统在监控摄像头监控的画面范围之内&#xff0c;对人的不安全行为&#xff08;违规行为&#xff09;或者物的不安全状态进行实时分析识别&#xff0c;当工地ai智能视频监控系统发现现场违规行为时&#xff0c;可根据需要设置各种警戒要求&#xff0c;工地ai…

【计算机网络--物理层】编码和调制与数据交换方式

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录基带信号与宽带信号基带信号宽带信号小结编码与调制编码调制的方法数字数据编码为数字信号数字数字调制为模拟信号模拟数据编码为数字信号模拟信号调制为模拟信号数据交换电路交换报文交换分组交换数据报方式…

windows系统命令行查看已连接过的WiFi密码

展示所有连接过的WiFi列表netsh wlan show profiles 显示具体某个WiFi的密码netsh wlan show profiles name="XXXXXX" key=clear name - 所要显示配置文件的名称。就是WiFi的名称 interface - 已配置此配置文件的接口的名称。 key - 以纯…

跨境电商万圣节社媒营销:8个方法助你冲出重围

今天是西方一年一度的万圣节前夜&#xff0c;同时也是跨境电商第四季度第一个大促日。Nox聚星获悉&#xff0c;2022年万圣节期间会有69%的美国民众参与这场万圣节狂欢&#xff0c;预计人均消费将达到100.45美金&#xff0c;预计将产生106亿的销售额。作为四季度第一个促销日&am…

【飞桨PaddleSpeech语音技术课程】— 多语言合成与小样本合成技术应用实践

(以下内容搬运自飞桨PaddleSpeech语音技术课程&#xff0c;点击链接可直接运行源码) 多语言合成与小样本合成技术应用实践 一 简介 1.1 语音合成的简介 语音合成是一种将文本转换成音频的技术。通常语音合成的整体流程如图1所示。可以分为&#xff1a;文本前端&#xff0c;…

团队分工越明确,工作效率越低?

一个团队各项任务能否顺利完成,关键看员工的执行力,而员工执行力的发挥,取决于组织对员工的合理分工。 分工合理,能调动员工的积极性,分工不合理,便会扼杀积极性。 那么如何才能做到合理分工呢?有些人认为分工就是把工作内容拆成一个个小任务,然后让员工去分头完成。…

C语言学习推荐---小游戏

文章目录控制台文字游戏srand、rand、time猜拳游戏控制台动作游戏运动的小球贪吃蛇音乐图形界面easyx介绍后续学习c语言的时候&#xff0c;想写例子&#xff0c;但是课后习题又太枯燥怎么办&#xff1f; 写小游戏可以锻炼我们的编程抽象能力和思维&#xff0c;而且比较有趣&…

基于nodejs电影交流网站设计与实现-计算机毕业设计源码+LW文档

摘 要 网络的广泛应用给生活带来了十分的便利。所以把电影交流管理与现在网络相结合&#xff0c;利用nodejs技术建设电影交流网站&#xff0c;实现电影交流的信息化。则对于进一步提高电影交流管理发展&#xff0c;丰富电影交流管理经验能起到不少的促进作用。 电影交流网站能…

论文研读1——对抗样本(Adversarial Example)综述

论文地址&#xff1a;Threat of Adversarial Attacks on Deep Learning in Computer Vision: A Survey 部分内容参考科研篇二&#xff1a;对抗样本&#xff08;Adversarial Example&#xff09;综述 一、主要内容 肯定了深度学习在计算机视觉等领域的贡献&#xff0c;但深度…

后端开发总结(2):go语言的知识点

go语言知识点1 append 列表2 如何打印指针结构体的值3 * 和 & 的用法1 append 列表 append() 切片需要增加 ... var a []inta append(a, 1) // 追加1个元素 a append(a, 1, 2, 3) // 追加多个元素 a append(a, []int{1,2,3}...) // 追加切片,2 如何打印指针结构体的值…

如何将程序打包成exe

我们经常需要将我们写的程序打包发给用户使用&#xff0c;很多时候为了方便会直接将文件夹或者压缩包发出去。这种方式对于一些不太懂电脑的用户来说的话&#xff0c;假如程序中有多个可执行文件&#xff0c;就会完全不知道怎么使用。众所周知&#xff0c;客户体验也是评判软件…

SpringBoot笔记:Hello World

SpringBoot简化了Spring应用的初始框架搭建和开发过程,利用SpringBoot框架可以快速的进行Spring应用的开发,SpringBoot具有以下特性:能够快速创建基于Spring的应用程序。 提供了约定好的初始POM来简化Maven配置,让Maven配置变得更简单。 多数情况可以直接使用注解开发来替代…

标准库类型string和vector

一、命名空间 std::cinstd就是命名空间&#xff0c; 这个的含义是 &#xff1a;编译器应该从操作符左侧的名字所示的作用域std中去寻找cin。 另一种方式就是在开头显式进行说明&#xff1a; using std::cin;这样一来后续就不用再去在每条语句中显式说明了。 需要注意的是&…

Java垃圾回收器

Java垃圾回收器1 GC分类与性能指标1.1 垃圾回收器概述1.2 垃圾回收器分类1.2.1 按照线程分1.2.2 按照工作模式分1.2.3 碎片处理方式分1.2.4 工作的内存区间分1.3 评估GC的性能指标1.4 吞吐量与暂停时间的对比说明1.4.1 吞吐量1.4.2 暂停时间1.4.3 高吞吐量 VS 暂停时间2 垃圾回…

非常实用的Visual Studio Code快捷键(2) 欢迎各位大侠补充

折叠或展开代码 代码须易于理解并且要记录在案。可以使用以下快捷键轻松折叠代码中次重要的部分&#xff1a; 按_Ctrl Shift [_ 进行折叠。按_Ctrl Shift ]_ 展开 导航到特定行 如果要转到包含数千行的文件中的所需行。只需执行以下操作&#xff1a; 按_Ctrl G_&#x…

wireshark测试tcp三次握手与四次挥手

wireshark 选择Loopback来监听本地网络。 监听的内容是分三大模块的&#xff1a; 封包列表的面板中显示&#xff0c;编号&#xff0c;时间戳&#xff0c;源地址&#xff0c;目标地址&#xff0c;协议&#xff0c;长度&#xff0c;以及封包信息。 你可以看到不同的协议用了…