文章目录
- 需求说明
- 实现思路
- 相关代码
需求说明
最近有个需求:用户点击上下移动可以实现对数据自定义排序,每次移动一个位置。具体如下图所示:
实现思路
- 数据库表中添加一个order字段,默认设置为和主键一样的值,数据按照order降序排列
由于MySQL表只能有一个自增的键(已设置为主键自增),所以这里的实现是每次插入数据后获取主键id的值,然后更新order字段的值(设置为id字段的值)。 - 上移操作
取出上一条记录的排序号,将当前记录与上一条记录的排序号调换位置 - 下移操作
取出下一条记录的排序号,将当前记录与下一条记录的排序号调换位置
相关代码
公告分类表脚本如下:
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实体,用于接收前端请求入参,代码如下:
@Data
public class AdjustOrderReq {
@ApiModelProperty(value="公告分类id")
private Integer id;
@ApiModelProperty(value="排序方式")
private Integer operaType;//1上移 2下移
}
Controller请求方法代码如下:
@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);
}
服务实现方法代码如下:
@Override
public int adjustOrder(AdjustOrderReq orderReq) {
// 1、查询是否存在分类
NoticeType noticeType = noticeTypeMapper.selectByPrimaryKey(orderReq.getId());
if(noticeType == null){
log.info("NoticeServiceImpl.adjustOrder未查询到公告分类!");
return -2;
}
// 2、上移
if(orderReq.getOperaType().equals(1)){
//查询下一条记录Id和sort
Integer nextId = noticeTypeMapper.selectNextId(noticeType);
NoticeType nextNotice = noticeTypeMapper.selectByPrimaryKey(nextId);
//更新下一条记录的sort为当前值
noticeType.setId(nextId);
noticeTypeMapper.updateSortById(noticeType);
//更新当前记录的sort为下一条
nextNotice.setId(orderReq.getId());
noticeTypeMapper.updateSortById(nextNotice);
}
// 3、下移动
if(orderReq.getOperaType().equals(2)){
//查询上一条记录Id和sort
Integer previousId = noticeTypeMapper.selectPreviousId(noticeType);
NoticeType previousNotice = noticeTypeMapper.selectByPrimaryKey(previousId);
//更新上一条记录的sort为当前值
noticeType.setId(previousId);
noticeTypeMapper.updateSortById(noticeType);
//更新当前记录的sort为上一条
previousNotice.setId(orderReq.getId());
noticeTypeMapper.updateSortById(previousNotice);
}
return 1;
}
MyBatis的XML映射文件代码如下:
<!--根据主键更新排序号-->
<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>
<!--根据sort查询上一条记录主键-->
<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>
<!--根据sort查询下一条记录主键-->
<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方法作用是根据主键查询,代码就不贴了。
若有更好的实现方案或者上续代码有任何问题,都欢迎交流!