利用周末时间,对自己的项目进行了升级,原来使用的是tkmybatis,改为mybatis-plus。但是返回数据的格式变了,导致前端的客户端排序失效了,于是决定在服务端实现排序。
目录

easyui的数据表格datagrid支持多字段排序,可以控制是否通过服务器排序,核心代码如下。
- 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>
在需要开启排序功能的字段后面添加sortable:true的选项
- let pageList = [10, 20, 50, 100];
-
- $(document).ready(function() {
- // 角色数据表格
- $("#role_list").datagrid({
- url: '/role_account/selectByPage',
- 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();
- }
- }, '-', {
- iconCls: 'icon-set',
- text: '加点',
- handler: function() {
- handleJiadian();
- }
- }, '-', {
- iconCls: 'icon-shield',
- text: '属性',
- handler: function() {
- handleAttribute();
- }
- }, '-', {
- iconCls: 'icon-search',
- text: '查看',
- handler: function() {
- handleView();
- }
- }, '-', {
- iconCls: 'icon-tip',
- text: '关于',
- handler: function() {
- handleTip();
- }
- }],
- columns: [[
- {field: 'id', title: '角色ID', align: "center", sortable: true, width:100},
- {field: 'name', title: '角色名', align: "center", width: 120},
- {field: 'modelingId', title: '角色造型', align: "center", width: 80
- , formatter: function(value, rowData, rowIndex) {
- get("/role_modeling/selectById", {
- id: value
- }, function(result) {
- $("#modeling_" + rowIndex).attr("src", result.image)
- .attr("title", result.name);
- }, error);
-
- return "
"; - }
- },
- {field: 'grade', title: '等级', align: "center", sortable: true, width: 80
- , 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 "" + value+ "级";
- }
- },
- {field: 'score', title: '人物评分', align: "center", sortable: true, width: 80},
- {field: 'schoolId', title: '门派', align: "center", width: 80
- , formatter: function(value, rowData, rowIndex) {
- get("/school/selectById", {
- id: value
- }, function(result) {
- $("#school_" + rowIndex).attr("src", result.image)
- .attr("title", result.name).width(size);
- }, error);
-
- return "
"; - }
- },
- {field: 'jinbi', title: '金币', align: "center", sortable: true, width: 80},
- {field: 'accountId', title: '账号', align: "center", width: 200
- , formatter: function(value, rowData, rowIndex) {
- get("/account/selectAccountById", {
- id: value
- }, function(response) {
- $("#account_" + rowIndex).html(response.data);
- }, error);
-
- return "";
- }
- },
- {field: "lastUpdateTime", title: "最后一次修改时间", align: "center", sortable: true, width: 125},
- {field: 'right', title: '操作', align: "center"
- , formatter: function(value, rowData, rowIndex) {
- + 'onclick="handleDelete(' + rowData.id + ')">'
- + '
'; - }
- }
- ]]
- });
-
- });
表格的multiSort选项设置为true表示允许多字段排序,remoteSort表示是否从服务器排序,设置为true,我们接下来在后台接口处理字段排序。
RoleAccountController.java
- @RestController
- @RequestMapping(path = "/role_account", produces="application/json; charset=utf-8")
- public class RoleAccountController {
- private final IRoleAccountService service;
-
- @Autowired
- public RoleAccountController(IRoleAccountService service) {
- this.service = service;
- }
-
- @ApiOperation("分页查询角色列表")
- @RequestMapping(value = "/selectByPage", method = RequestMethod.POST)
- public JsonResult
> selectByPage(RoleAccountPager pager) { - Page
page = service.selectByPage(pager); -
- return JsonResult.restPage(page);
- }
-
- }
RoleAccountServiceImpl.java
- @Service
- public class RoleAccountServiceImpl implements RoleAccountService {
- @Override
- public Page
selectByPage(RoleAccountPager pager) { - Page
page = new Page<>(pager.getPage(), pager.getRows()); - QueryWrapper
wrapper = new QueryWrapper<>(); -
- wrapper.eq(
- !StringUtils.isEmpty(pager.getId()),
- "id", pager.getId());
- wrapper.like(
- !StringUtils.isEmpty(pager.getName()),
- "name", pager.getName()
- );
- wrapper.eq(
- pager.getSchoolId() != null,
- "school_id", pager.getSchoolId()
- );
- wrapper.eq(
- pager.getModelingId() != null,
- "modeling_id", pager.getModelingId()
- );
- wrapper.eq(
- !StringUtils.isEmpty(pager.getAccountId()),
- "account_id", pager.getAccountId()
- );
-
- // 得到order by语句
- String statement = Pager.getOrderByStatement(pager);
- wrapper.last(statement);
-
- return mapper.selectPage(page, wrapper);
- }
-
- }
RoleAccountMapper.java
@Repository public interface RoleAccountMapper extends BaseMapper{ }
- @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;
- }
接收前端传递的查询参数
- @Data
- @EqualsAndHashCode(callSuper = true)
- public class RoleAccountPager extends Pager {
- /**
- * 角色id
- */
- private String id;
-
- /**
- * 角色名
- */
- private String name;
-
- /**
- * 等级
- */
- private Integer grade;
-
- /**
- * 账号id
- */
- private String accountId;
-
- /**
- * 门派id
- */
- private Integer schoolId;
-
- /**
- * 角色造型id
- */
- private Integer modelingId;
- }
- /**
- * 基础分页对象,包含页数和每页的记录数
- */
- @Data
- @EqualsAndHashCode(callSuper = true)
- public class Pager extends Sorter {
- /**
- * 页数
- */
- private Integer page = 1;
-
- /**
- * 每页记录数
- */
- private Integer rows = 10;
- }

以上是easyui官网的相关截图,当多字段排序时,传递给后台的参数中通过逗号拼接。
【例如】:通过评分score升序和等级grade降序排序时,后台接收到的参数为:
{
"sort": "score,grade"
"order": "asc,desc"
}
于是基于此规则,在Sorter.java中提供一个处理排序字段的方法
- /**
- * 基础排序对象,包含排序字段和排序方式
- */
- @Data
- public class Sorter {
- /**
- * 排序字段
- */
- private String sort;
-
- /**
- * 排序方式:asc/desc
- */
- private String order;
-
- /**
- * 根据查询条件拼接得到order by语句
- * @param sorter 分页查询条件
- * @return String
- */
- public static String getStatement(Sorter sorter) {
- String sort;
- String[] sortArray = {};
- String[] orderArray = {};
- String order = sorter.getOrder();
- String sortColumn = sorter.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 sorter 分页查询条件
- * @return String
- */
- public static String getOrderByStatement(Sorter sorter) {
- String statement = getStatement(sorter);
-
- if (StringUtils.isNotEmpty(statement)) {
- return " order by " + statement;
- } else {
- return statement;
- }
- }
-
- }
因为排序的字段名是驼峰命名,需要转为小写字母+下划线命名,转换的方法抽象到了StringUtils工具类中,代码如下。
- public class StringUtils {
-
- /**
- * 功能:驼峰命名转下划线命名
- * 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写
- * @param str 待转换的字符串
- * @return String
- */
- public static String toLowerCase(String str) {
- str = str.replaceAll("([a-z])([A-Z])", "$1_$2");
-
- return str.toLowerCase();
- }
-
- }
通过继承关系,我们控制器接口的参数类型继承自Pager
- String statement = Pager.getOrderByStatement(pager);
-
- wrapper.last(statement);
好了,文章就分享到这里了,看完不要忘了点赞+收藏哦~