分享一下项目中遇到的排序失效问题

本文描述了作者对查询接口服务中的代码进行优化,删除了十几行冗余代码,并更新了MyBatis映射文件中的动态SQL,解决了排序失效问题,确保了前端按照预期正确排序。
摘要由CSDN通过智能技术生成

今天把原来的一个查询接口的业务代码进行了优化,减少了十几行冗余的代码。

原来的代码

ChongwuServiceImpl.java

/**
 * @author heyunlin
 * @version 1.0
 */
@Slf4j
@Service
public class ChongwuServiceImpl implements ChongwuService {

    @Override
	public JsonResult<JsonPage<Chongwu>> selectByPage(ChongwuPager pager) {
		List<Integer> skillIds = pager.getSkillIds();

		if (CollectionUtils.isNotEmpty(skillIds)) {
			int size = skillIds.size();
			// 得到order by语句
			String statement = Pager.getOrderByStatement(pager);

			List<Chongwu> rows = chongwuMapper.selectBySkills(pager, skillIds, size, statement);
			long total = chongwuMapper.selectCountBySkills(pager, skillIds, size);

			return JsonResult.restPage(total, rows);
		} else {
			Page<Chongwu> page = new Page<>(pager.getPage(), pager.getRows());
			QueryWrapper<Chongwu> wrapper = new QueryWrapper<>();

			wrapper.eq(
					pager.getCategoryId() != null,
					"category_id", pager.getCategoryId()
			);
			wrapper.eq(
					StringUtils.isNotEmpty(pager.getRoleId()),
					"role_id", pager.getRoleId()
			);
			wrapper.eq(
					StringUtils.isNotEmpty(pager.getZuoqiId()),
					"zuoqi_id", pager.getZuoqiId()
			);

			// 得到order by语句
			String statement = Pager.getOrderByStatement(pager);
			wrapper.last(statement);

			Page<Chongwu> result = chongwuMapper.selectPage(page, wrapper);

			return JsonResult.restPage(result);
		}
	}

}

ChongwuMapper.java

@Repository
public interface ChongwuMapper extends BaseMapper<Chongwu> {

	/**
	 * 查询已学习指定技能的宠物数量
	 * @param pager 分页参数
	 * @param skillIds 宠物技能类型id列表
	 * @param total 总技能数
	 * @return int
	 */
	long selectCountBySkills(
			@Param("pager") ChongwuPager pager,
			@Param("skillIds") List<Integer> skillIds,
			@Param("total") int total
	);

	/**
	 * 查询已学习指定技能的宠物
	 * @param pager 分页参数
	 * @param skillIds 宠物技能类型id列表
	 * @param total 总技能数
	 * @param statement order by后面的语句
	 * @return List<Chongwu>
	 */
	List<Chongwu> selectBySkills(
			@Param("pager") ChongwuPager pager,
			@Param("skillIds") List<Integer> skillIds,
			@Param("total") int total,
			@Param("statement") String statement
	);
}

ChongwuMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.edu.sgu.www.mhxysy.mapper.chongwu.ChongwuMapper">
    <resultMap id="resultMap" type="cn.edu.sgu.www.mhxysy.entity.chongwu.Chongwu">
        <result column = "id" property = "id" />
        <result column = "name" property = "name" />
        <result column = "type" property = "type" />
        <result column = "grade" property = "grade" />
        <result column = "score" property = "score" />
        <result column = "role_id" property = "roleId" />
        <result column = "zuoqi_id" property = "zuoqiId" />
        <result column = "zizhi_id" property = "zizhiId" />
        <result column = "lifespan" property = "lifespan" />
        <result column = "ty_status" property = "tyStatus" />
        <result column = "category_id" property = "categoryId" />
        <result column = "attribute_id" property = "attributeId" />
    </resultMap>

    <select id="selectCountBySkills" resultType="long">
        select count(*) from chongwu where id in (
            select cs.chongwu_id from (
                select chongwu_id from chongwu_skill where skill_id in (
                    <foreach item='skillId' collection='skillIds' separator=','>
                        #{skillId}
                    </foreach>
                )
            ) as cs
            group by cs.chongwu_id
            having count(cs.chongwu_id) >= #{total}
        )
        <if test='pager.zuoqiId != null and pager.zuoqiId != ""'>
            and zuoqi_id = #{pager.zuoqiId}
        </if>
        <if test='pager.roleId != null and pager.roleId != ""'>
            and role_id = #{pager.roleId}
        </if>
        <if test='pager.categoryId != null'>
            and category_id = #{pager.categoryId}
        </if>
    </select>

    <select id="selectBySkills" resultMap="resultMap">
        select * from chongwu where id in (
            select cs.chongwu_id from (
                select chongwu_id from chongwu_skill where skill_id in (
                    <foreach item='skillId' collection='skillIds' separator=','>
                        #{skillId}
                    </foreach>
                )
            ) as cs
            group by cs.chongwu_id
            having count(cs.chongwu_id) >= #{total}
        )
        <if test='pager.zuoqiId != null and pager.zuoqiId != ""'>
            and zuoqi_id = #{pager.zuoqiId}
        </if>
        <if test='pager.roleId != null and pager.roleId != ""'>
            and role_id = #{pager.roleId}
        </if>
        <if test='pager.categoryId != null'>
            and category_id = #{pager.categoryId}
        </if>
        order by role_id, #{statement}
    </select>
</mapper>

重构后的代码

ChongwuServiceImpl.java

/**
 * @author heyunlin
 * @version 1.0
 */
@Slf4j
@Service
public class ChongwuServiceImpl implements ChongwuService {

    @Override
	public Page<Chongwu> selectByPage(ChongwuPager pager) {
		List<Integer> skillIds = pager.getSkillIds();

		pager.setTotal(skillIds != null ? skillIds.size() : 0);
		pager.setStatement(Pager.getStatement(pager));

		Page<Chongwu> page = Pager.ofPage(pager);

		return chongwuMapper.selectPage(page, pager);
	}

}

ChongwuMapper.java

@Repository
public interface ChongwuMapper extends BaseMapper<Chongwu> {

	/**
	 * 分页查询宠物列表
	 * @param page 分页参数
	 * @param pager 查询条件
	 * @return List<Chongwu>
	 */
	Page<Chongwu> selectPage(Page<Chongwu> page, ChongwuPager pager);
}

ChongwuMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.edu.sgu.www.mhxysy.mapper.chongwu.ChongwuMapper">
    <resultMap id="resultMap" type="cn.edu.sgu.www.mhxysy.entity.chongwu.Chongwu">
        <result column = "role_id" property = "roleId" />
        <result column = "zuoqi_id" property = "zuoqiId" />
        <result column = "zizhi_id" property = "zizhiId" />
        <result column = "ty_status" property = "tyStatus" />
        <result column = "category_id" property = "categoryId" />
        <result column = "attribute_id" property = "attributeId" />
    </resultMap>

    <select id="selectPage" resultMap="resultMap">
        select * from chongwu
        <where>
            1 = 1
            <if test='pager.total > 0'>
                and id in (
                    select cwjnb.chongwu_id from (
                        select chongwu_id from chongwu_skill where skill_id in (
                            <foreach item="skillId" collection="pager.skillIds" separator=",">
                                #{skillId}
                            </foreach>
                        )
                    ) as cwjnb
                    group by cwjnb.chongwu_id
                    having count(cwjnb.chongwu_id) >= #{pager.total}
                )
            </if>
            <if test="pager.zuoqiId != null and pager.zuoqiId != ''">
                and zuoqi_id = #{pager.zuoqiId}
            </if>
            <if test="pager.roleId != null and pager.roleId != ''">
                and role_id = #{pager.roleId}
            </if>
            <if test='pager.categoryId != null'>
                and category_id = #{pager.categoryId}
            </if>
        </where>

        <if test="pager.statement != null and pager.statement != ''">
            order by #{pager.statement}
        </if>
    </select>
</mapper>

排序失效问题

修改后引发了前端排序失效问题,点击排序图标触发了重新渲染表格数据的ajax请求,而且控制台打印的SQL语句也没有问题,直接复制到数据库中执行,能查出排序后的数据。

前端排序失效截图

控制台打印的SQL查询语句

直接复制到Navicat中执行,查询到了正确的结果(score列按升序排序)

问题原因分析

遇到这个问题其实仔细一想非常简单,就是${}和#{}的区别,把#{}改为${}即可。

这是把#{}改成${}之后,在控制台的SQL语句,两者有一定的区别:

  • 上图的SQL语句:select * from chongwu WHERE 1 = 1 order by role_id , "score desc" LIMIT 10
  • 下图的SQL语句:select * from chongwu WHERE 1 = 1 order by role_id , score desc LIMIT 10

纠正后的代码

ChongwuMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.edu.sgu.www.mhxysy.mapper.chongwu.ChongwuMapper">
    <resultMap id="resultMap" type="cn.edu.sgu.www.mhxysy.entity.chongwu.Chongwu">
        <result column = "id" property = "id" />
        <result column = "name" property = "name" />
        <result column = "type" property = "type" />
        <result column = "grade" property = "grade" />
        <result column = "score" property = "score" />
        <result column = "role_id" property = "roleId" />
        <result column = "zuoqi_id" property = "zuoqiId" />
        <result column = "zizhi_id" property = "zizhiId" />
        <result column = "lifespan" property = "lifespan" />
        <result column = "ty_status" property = "tyStatus" />
        <result column = "category_id" property = "categoryId" />
        <result column = "attribute_id" property = "attributeId" />
    </resultMap>

    <select id="selectPage" resultMap="resultMap">
        select * from chongwu
        <where>
            1 = 1
            <if test='pager.total > 0'>
                and id in (
                    select cwjnb.chongwu_id from (
                        select chongwu_id from chongwu_skill where skill_id in (
                            <foreach item="skillId" collection="pager.skillIds" separator=",">
                                #{skillId}
                            </foreach>
                        )
                    ) as cwjnb
                    group by cwjnb.chongwu_id
                    having count(cwjnb.chongwu_id) >= #{pager.total}
                )
            </if>
            <if test="pager.zuoqiId != null and pager.zuoqiId != ''">
                and zuoqi_id = #{pager.zuoqiId}
            </if>
            <if test="pager.roleId != null and pager.roleId != ''">
                and role_id = #{pager.roleId}
            </if>
            <if test='pager.categoryId != null'>
                and category_id = #{pager.categoryId}
            </if>
        </where>

        <if test="pager.statement != null and pager.statement != ''">
            order by ${pager.statement}
        </if>
    </select>
</mapper>

重新启动项目之后,问题得以解决,不知道有没有大佬遇到类似的问题,欢迎评论区留言分享~

好了,文章就分享到这里了,看完不要忘了点赞+收藏哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值