需求说明 
最近有个需求:用户点击上下移动可以实现对数据自定义排序,每次移动一个位置。具体如下图所示: 
实现思路 
数据库表中添加一个order字段,默认设置为和主键一样的值,数据按照order降序排列 
由于MySQL表只能有一个自增的键 (已设置为主键自增),所以这里的实现是每次插入数据后获取主键id的值,然后更新order字段的值(设置为id字段的值)。 
上移操作 
取出上一条记录的排序号,将当前记录与上一条记录的排序号调换位置 
下移操作 
取出下一条记录的排序号,将当前记录与下一条记录的排序号调换位置 
 
 
相关代码 
公告分类表脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 CREATE  TABLE  `t_notice_type` (  `id` int (11 ) NOT  NULL  AUTO_INCREMENT COMMENT '公告分类 id' ,   `name` varchar (255 ) DEFAULT  NULL  COMMENT '分类名称' ,   `icon` varchar (255 ) DEFAULT  NULL  COMMENT '公告图标' ,   `status` int (1 ) DEFAULT  NULL  COMMENT '状态  0  开启  1  关闭' ,   `sort` int (3 ) NOT  NULL  DEFAULT  '-1'  COMMENT '排序' ,   `create_time` datetime DEFAULT  NULL  COMMENT '创建时间' ,   `update_time` datetime DEFAULT  NULL  COMMENT '修改时间' ,   `create_user` int (11 ) DEFAULT  NULL  COMMENT '创建者' ,   `last_update_user` int (11 ) DEFAULT  NULL  COMMENT '最后修改人' ,   PRIMARY  KEY (`id`) USING  BTREE ) ENGINE= InnoDB AUTO_INCREMENT= 12  DEFAULT  CHARSET= utf8 ROW_FORMAT= DYNAMIC  
 
AdjustOrderReq实体,用于接收前端请求入参,代码如下:
1 2 3 4 5 6 7 8 9 @Data public  class  AdjustOrderReq  {    @ApiModelProperty(value="公告分类id")      private  Integer id;     @ApiModelProperty(value="排序方式")      private  Integer operaType; } 
 
Controller请求方法代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @PostMapping("/adjustorder") @ApiOperation("公告分类顺序调整") public  ResponseMsg adjustOrder (@RequestBody  AdjustOrderReq orderReq) {    if (!ObjectUtil.checkIsNotNull(orderReq)){         return  this .errorRsp(MessageCode.Param_NULL);     }     if (!orderReq.getOperaType().equals(1 ) && !orderReq.getOperaType().equals(2 )){         return  this .errorRsp(MessageCode.Param_Error);     }     int  a  =  noticeTypeService.adjustOrder(orderReq);     if (a != 1 ){         return  this .errorRsp(MessageCode.Update_Error,String.valueOf(a));     }     return  this .successRsp(a); } 
 
服务实现方法代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Override  public  int  adjustOrder (AdjustOrderReq orderReq)  {            NoticeType  noticeType  =  noticeTypeMapper.selectByPrimaryKey(orderReq.getId());      if (noticeType == null ){          log.info("NoticeServiceImpl.adjustOrder未查询到公告分类!" );          return  -2 ;      }            if (orderReq.getOperaType().equals(1 )){                    Integer  nextId  =  noticeTypeMapper.selectNextId(noticeType);          NoticeType  nextNotice  =   noticeTypeMapper.selectByPrimaryKey(nextId);                    noticeType.setId(nextId);          noticeTypeMapper.updateSortById(noticeType);                    nextNotice.setId(orderReq.getId());          noticeTypeMapper.updateSortById(nextNotice);      }            if (orderReq.getOperaType().equals(2 )){                    Integer  previousId  =  noticeTypeMapper.selectPreviousId(noticeType);          NoticeType  previousNotice  =   noticeTypeMapper.selectByPrimaryKey(previousId);                    noticeType.setId(previousId);          noticeTypeMapper.updateSortById(noticeType);                    previousNotice.setId(orderReq.getId());          noticeTypeMapper.updateSortById(previousNotice);      }      return  1 ;  } 
 
MyBatis的XML映射文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <update  id ="updateSortById"  parameterType ="com.aspirecn.rewardmanagement.entity.NoticeType"  >   update t_notice_type   set sort = #{sort},update_time = now()   where id = #{id,jdbcType=INTEGER} </update > <select  id ="selectPreviousId"  resultType ="java.lang.Integer"  parameterType ="com.aspirecn.rewardmanagement.entity.NoticeType" >   SELECT IFNULL(   (SELECT id FROM t_notice_type WHERE sort <  #{sort}   ORDER BY  sort DESC LIMIT 0,1),1   ) AS preTypeId </select > <select  id ="selectNextId"  resultType ="java.lang.Integer"  parameterType ="com.aspirecn.rewardmanagement.entity.NoticeType" >   SELECT IFNULL(   (SELECT id FROM t_notice_type WHERE sort >  #{sort}   ORDER BY  sort asc LIMIT 0,1),1   ) AS nextTypeId </select > 
 
selectByPrimaryKey方法作用是根据主键查询,代码就不贴了。 
若有更好的实现方案或者上续代码有任何问题,都欢迎交流! 
参考链接