mybatis中orderBy(排序字段)和sort(排序方式)引起的bug及解决

 更新时间:2022年01月30日 09:35:24   作者:意田天  
这篇文章主要介绍了mybatis中orderBy(排序字段)和sort(排序方式)引起的bug,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

引言

记录一个mybatis实现动态字段的排序和动态的升降序问题

实现效果如下:

在这里插入图片描述

问题叙述

在这里插入图片描述

在这里无论使用postman是否传递sort的值, 都不生效,

postman

在这里插入图片描述

执行的sql日志

==>  Preparing: select sum(acd.read_view_count) as read_view_count,sum(acd.read_person_count) as read_person_count, sum(acd.like_count) as like_count,sum(acd.comment_count) as comment_count, sum(acd.collect_count) as collect_count,sum(acd.transmit_count) as transmit_count, avg(acd.avg_stay_time) as avg_stay_time,avg(acd.visit_count) as visit_count, acd.article_id, acd.article_title from article_content_data acd left join cplatform cp on cp.cid = acd.platform_id WHERE 1=1 group by acd.article_id desc order by transmit_count 
==> Parameters: 
<==    Columns: read_view_count, read_person_count, like_count, comment_count, collect_count, transmit_count, avg_stay_time, visit_count, article_id, article_title
<==        Row: 900, 900, 960, 390, 12592, 423, 1548.3333, 1.0000, 3, 这是一个正经的文章标题3
<==        Row: 1500, 1500, 1560, 390, 1497, 423, 5294.6667, 1.0000, 5, 这是一个正经的文章标题5
<==        Row: 400, 440, 480, 520, 526, 546, 419.0000, 1.0000, 1, 震惊, 百分之99的人在喝了睡之后, 100年之内会死
<==        Row: 800, 800, 880, 520, 2587, 777, 426.2500, 1.0000, 2, 这是一个正经的文章标题2
<==        Row: 1200, 1200, 1260, 390, 386, 816, 121.0000, 1.0000, 4, 这是一个正经的文章标题4
<==      Total: 5

**很明显, order by之后只拼了排序字段, 而没有拼上排序方式 **

下面尝试采用第二种方式

将排序sql语句替换为以下这个

                order by
                ${orderBy}
                <choose>
                    <when test="sort!=null">
                        ${sort}
                    </when>
                    <otherwise>
                        asc
                    </otherwise>
                </choose>

完整代码如下

    <select id="listArticleContentDataDTO" resultType="com.etouch.pojo.dto.data.ArticleContentDataDTO">
        select
        sum(acd.read_view_count) as read_view_count,sum(acd.read_person_count) as read_person_count,
        sum(acd.like_count) as like_count,sum(acd.comment_count) as comment_count,
        sum(acd.collect_count) as collect_count,sum(acd.transmit_count) as transmit_count,
        avg(acd.avg_stay_time) as avg_stay_time,avg(acd.visit_count) as visit_count,
        acd.article_id, acd.article_title
        from article_content_data acd
        left join cplatform cp on cp.cid = acd.platform_id
        <include refid="searchArticleData"/>
        group by acd.article_id
        order by
        ${orderBy}
        <choose>
            <when test="sort!=null">
                ${sort}
            </when>
            <otherwise>
                asc
            </otherwise>
        </choose>
    </select>

执行查询,结果如下

==>  Preparing: SELECT sum(acd.read_view_count) AS read_view_count, sum(acd.read_person_count) AS read_person_count, sum(acd.like_count) AS like_count, sum(acd.comment_count) AS comment_count, sum(acd.collect_count) AS collect_count, sum(acd.transmit_count) AS transmit_count, avg(acd.avg_stay_time) AS avg_stay_time, avg(acd.visit_count) AS visit_count, acd.article_id, acd.article_title FROM article_content_data acd LEFT JOIN cplatform cp ON cp.cid = acd.platform_id WHERE 1 = 1 GROUP BY acd.article_id order by transmit_count 
==> Parameters: 
<==    Columns: read_view_count, read_person_count, like_count, comment_count, collect_count, transmit_count, avg_stay_time, visit_count, article_id, article_title
<==        Row: 900, 900, 960, 390, 12592, 423, 1548.3333, 1.0000, 3, 这是一个正经的文章标题3
<==        Row: 1500, 1500, 1560, 390, 1497, 423, 5294.6667, 1.0000, 5, 这是一个正经的文章标题5
<==        Row: 400, 440, 480, 520, 526, 546, 419.0000, 1.0000, 1, 震惊, 百分之99的人在喝了睡之后, 100年之内会死
<==        Row: 800, 800, 880, 520, 2587, 777, 426.2500, 1.0000, 2, 这是一个正经的文章标题2
<==        Row: 1200, 1200, 1260, 390, 386, 816, 121.0000, 1.0000, 4, 这是一个正经的文章标题4
<==      Total: 5

同样是没有实现排序,此时应该考虑,mybatis是否无法同时接受orderBy和sort都是变量的情况, 带着这个疑问, 将order by的排序字段设置为固定值, sort设置为前端传递过来的值, 代码如下

        order by
        acd.like_count
        <choose>
            <when test="sort!=null">
                ${sort}
            </when>
            <otherwise>
                asc
            </otherwise>
        </choose>

执行sql日志如下

==>  Preparing: select sum(acd.read_view_count) as read_view_count,sum(acd.read_person_count) as read_person_count, sum(acd.like_count) as like_count,sum(acd.comment_count) as comment_count, sum(acd.collect_count) as collect_count,sum(acd.transmit_count) as transmit_count, avg(acd.avg_stay_time) as avg_stay_time,avg(acd.visit_count) as visit_count, acd.article_id, acd.article_title from article_content_data acd left join cplatform cp on cp.cid = acd.platform_id WHERE 1=1 group by acd.article_id order by acd.like_count asc 
==> Parameters: 
<==    Columns: read_view_count, read_person_count, like_count, comment_count, collect_count, transmit_count, avg_stay_time, visit_count, article_id, article_title
<==        Row: 400, 440, 480, 520, 526, 546, 419.0000, 1.0000, 1, 震惊, 百分之99的人在喝了睡之后, 100年之内会死
<==        Row: 800, 800, 880, 520, 2587, 777, 426.2500, 1.0000, 2, 这是一个正经的文章标题2
<==        Row: 900, 900, 960, 390, 12592, 423, 1548.3333, 1.0000, 3, 这是一个正经的文章标题3
<==        Row: 1200, 1200, 1260, 390, 386, 816, 121.0000, 1.0000, 4, 这是一个正经的文章标题4
<==        Row: 1500, 1500, 1560, 390, 1497, 423, 5294.6667, 1.0000, 5, 这是一个正经的文章标题5
<==      Total: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32112885]

这里发现实现了升降序, 但是这样不能满足原型上的要求, 动态的字段排序和升降序

这里不妨换种方式思考, 假如将排序字段和排序方式拼的一起, 存放到一个字段里呢? 带着这个猜想, 进行第三种方式

第三种方式

代码

 <choose>
            <when test="orderBy!=null and orderBy!=''">
                order by ${orderBy}
            </when>
            <otherwise>
                order by acd.create_time asc
            </otherwise>
        </choose>

3.1 首先是什么都不传

在这里插入图片描述

直接sql结果如下

==>  Preparing: select sum(acd.read_view_count) as read_view_count,sum(acd.read_person_count) as read_person_count, sum(acd.like_count) as like_count,sum(acd.comment_count) as comment_count, sum(acd.collect_count) as collect_count,sum(acd.transmit_count) as transmit_count, avg(acd.avg_stay_time) as avg_stay_time,avg(acd.visit_count) as visit_count, acd.article_id, acd.article_title from article_content_data acd left join cplatform cp on cp.cid = acd.platform_id WHERE 1=1 group by acd.article_id order by acd.create_time asc 
==> Parameters: 
<==    Columns: read_view_count, read_person_count, like_count, comment_count, collect_count, transmit_count, avg_stay_time, visit_count, article_id, article_title
<==        Row: 400, 440, 480, 520, 526, 546, 419.0000, 1.0000, 1, 震惊, 百分之99的人在喝了睡之后, 100年之内会死
<==        Row: 800, 800, 880, 520, 2587, 777, 426.2500, 1.0000, 2, 这是一个正经的文章标题2
<==        Row: 900, 900, 960, 390, 12592, 423, 1548.3333, 1.0000, 3, 这是一个正经的文章标题3
<==        Row: 1200, 1200, 1260, 390, 386, 816, 121.0000, 1.0000, 4, 这是一个正经的文章标题4
<==        Row: 1500, 1500, 1560, 390, 1497, 423, 5294.6667, 1.0000, 5, 这是一个正经的文章标题5
<==      Total: 5

默认采用创建日期排序, 避免前端不传排序字段导致报错

3.2 传入排序字段oderBy

在这里插入图片描述

这里将排序字段和排序方式用空格隔开, 存入orderBy中

查看sql执行结果

==>  Preparing: SELECT sum(acd.read_view_count) AS read_view_count, sum(acd.read_person_count) AS read_person_count, sum(acd.like_count) AS like_count, sum(acd.comment_count) AS comment_count, sum(acd.collect_count) AS collect_count, sum(acd.transmit_count) AS transmit_count, avg(acd.avg_stay_time) AS avg_stay_time, avg(acd.visit_count) AS visit_count, acd.article_id, acd.article_title FROM article_content_data acd LEFT JOIN cplatform cp ON cp.cid = acd.platform_id WHERE 1 = 1 GROUP BY acd.article_id order by like_count desc 
==> Parameters: 
<==    Columns: read_view_count, read_person_count, like_count, comment_count, collect_count, transmit_count, avg_stay_time, visit_count, article_id, article_title
<==        Row: 1500, 1500, 1560, 390, 1497, 423, 5294.6667, 1.0000, 5, 这是一个正经的文章标题5
<==        Row: 1200, 1200, 1260, 390, 386, 816, 121.0000, 1.0000, 4, 这是一个正经的文章标题4
<==        Row: 900, 900, 960, 390, 12592, 423, 1548.3333, 1.0000, 3, 这是一个正经的文章标题3
<==        Row: 800, 800, 880, 520, 2587, 777, 426.2500, 1.0000, 2, 这是一个正经的文章标题2
<==        Row: 400, 440, 480, 520, 526, 546, 419.0000, 1.0000, 1, 震惊, 百分之99的人在喝了睡之后, 100年之内会死
<==      Total: 5

很明显, 实现了动态排序, 大功告成, 接下来我会继续研究,到底是为什么myabtis不能同时接受orderBy和sort同时为变量的情况, 欢迎评论区补充

ps:order by或者group by后面不可以使用#{变量}的方式, 因为mybatis会把#{变量}进行预编译, 这也是为了防止sql注入, 也就是编译成了order by ‘字段名’ , 也就会导致排序失败, 这里只能采用${变量}的方式, ${}中的内容会不经过编译直接拼到order by后面, 但是不能避免sql注入, 可以再后台通过限制order by变量长度的方式, 来避免sql注入, 是麻烦了点, 但是鱼和熊掌不可兼得

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java删除二叉搜索树最大元素和最小元素的方法详解

    Java删除二叉搜索树最大元素和最小元素的方法详解

    这篇文章主要介绍了Java删除二叉搜索树最大元素和最小元素的方法,结合实例形式详细分析了java针对二叉搜索树的基本遍历、查找、判断、删除等相关操作技巧,需要的朋友可以参考下
    2020-03-03
  • 微信支付java版本之查询订单

    微信支付java版本之查询订单

    这篇文章主要为大家详细介绍了微信支付java版本之查询订单,为大家分享了微信支付订单的查询接口,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • SpringDataJpa如何使用union多表分页条件查询

    SpringDataJpa如何使用union多表分页条件查询

    这篇文章主要介绍了SpringDataJpa如何使用union多表分页条件查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 使用dom4j解析xml文件,并转出json格式问题

    使用dom4j解析xml文件,并转出json格式问题

    这篇文章主要介绍了使用dom4j解析xml文件,并转出json格式问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • SpringBoot读取Resource目录下文件的四种方式总结

    SpringBoot读取Resource目录下文件的四种方式总结

    在Spring Boot项目中,经常需要获取resources目录下的文件,这些文件可以包括配置文件、模板文件、静态资源等,本文将介绍四种常用的方法来获取resources目录下的文件,需要的朋友可以参考下
    2023-08-08
  • java必学必会之方法的重载(overload)

    java必学必会之方法的重载(overload)

    java必学必会之方法的重载,介绍了方法的重载、构造方法的重载,想要学好java方法的重载的朋友一定要好好阅读这篇文章
    2015-12-12
  • 浅谈Java 8 新增函数式接口到底是什么

    浅谈Java 8 新增函数式接口到底是什么

    这篇文章主要介绍了浅谈Java 8 新增函数式接口到底是什么,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • Java顺序查找算法详解

    Java顺序查找算法详解

    顺序查找又称线性查找,主要用于在线性表中进行查找。顺序查找通常分为对一般的无序线性表的顺序查找和对按关键字有序的顺序表的顺序查找,下面我们来一探究竟
    2022-08-08
  • Spring:如何使用枚举参数

    Spring:如何使用枚举参数

    这篇文章主要介绍了springboot枚举类型传递的步骤,帮助大家更好的理解和学习使用springboot,感兴趣的朋友可以了解下,希望能给你带来帮助
    2021-08-08
  • 一次因HashSet引起的并发问题详解

    一次因HashSet引起的并发问题详解

    这篇文章主要给大家介绍了一次因HashSet引起的并发问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11

最新评论