Mybatis实现动态排序方式

 更新时间:2022年10月25日 11:01:10   作者:LitongZero  
这篇文章主要介绍了Mybatis实现动态排序方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Mybatis实现动态排序

在数据展示时,很有可能碰到,需要动态排序的需求。当数据比较少的时候,还可以前端排序,但是,当数据非常大,尤其是涉及到分页的时候,就必须要用后端解决了。

以下,提供一种后端动态排序解决方案。

比如,现在我要查询用户信息(User)表。

可以在查询时,接口中,多添加两个字段。

  • orderField(排序列)
  • orderType(排序规则,升降序)

之后,在mapper.xml中的查询列表方法,添加

SELECT 
name , sex , age , user_grade as userGrade
FROM user
<if test="orderField !=null and orderField != '' ">
    order by ${orderField}  ${orderType}
</if>

注意事项:使用这样连续拼接两个注入参数时,只能用${},不能用#{}。

详情可以查看解释

这时,在我们查询时,可以在传入参数

User user = new User();
//以user_grade字段排序
user.setOrderField("user_grade");
//降序
user.setOrderType("desc");
//可在User类中添加
//在未传入时,使用set注入,设置默认值
public String getOrderField() {
        if (orderField == null || "".equals(orderField)) {
            orderField = "create_time";
        }
        return orderField;
    }
    public String getOrderType() {
        if (orderType == null || "".equals(orderType)) {
            orderType = "desc";
        }
        return orderType;
    }

如果,你觉得传入数据库中字段user_grade很不舒服的话。可以这样写SQL

SELECT 
name , sex , age , user_grade as userGrade
FROM user
<if test="orderField != null" >
    ORDER BY
    <choose>
        <when test="orderField == 'name'">
            name ${orderType}
        </when>
        <when test="orderField == 'age'">
            age ${orderType}
        </when>
        <when test="orderField == 'userGrade'">
            user_grade ${orderType}
        </when>
        <otherwise>
            create_time ${orderType}
        </otherwise>
    </choose>
</if>

然后再传入字段时,就这样

user.setOrderField("userGrade");

Mybatis动态排序不生效问题

sql如下:

select * from  table_name order by #{field}

造成问题原因

mybatis动态参数

#{}方式传参数会使用preparedstatement预编译处理方式,参数是以?占位符的方式传递。可以看到mybaits的sql日志如下:

==> Preparing: SELECT * FROM table_name ORDER BY ?
==> Parameters: time(String)

preparedstatement预编译方式的参数替换的原理1可知预编译方式会对参数加上’'引号,生成的最终sql如下:

SELECT * FROM table_name ORDER BY 'time'

以上sql数据库不能正常解析 order by 后面的字段,这就是我们排序失效的原因

解决办法

将#{}参数方式改成${}参数方式即可。

原因: ${}参数的方式是简单的字符串替换。

在动态解析阶段,该 sql 语句会被解析成:

select * from table_name order by time

小结一下:

  • #{}方式传参数只能处理值参数 不能传递表名,字段等参数
  • ${}字符串替换,可以动态处理表名,字段参数,但是使用这种方式必须注意sql注入的风险,对参数做好校验处理

备注:preparedstatement具体实现原理见:com.mysql.jdbc.PreparedStatement中的setString方法源码

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

相关文章

  • 新版idea创建spring boot项目的详细教程

    新版idea创建spring boot项目的详细教程

    这篇文章给大家介绍了新版idea创建spring boot项目的详细教程,本教程对新手小白友好,若根据教程创建出现问题导致失败可下载我提供的源码,在文章最后,本教程较新,文中通过图文给大家介绍的非常详细,感兴趣的朋友可以参考下
    2024-01-01
  • 关于Kill指令停掉Java程序的问题

    关于Kill指令停掉Java程序的问题

    这篇文章主要介绍了Kill指令停掉Java程序的思考,主要探究kill指令和java的关闭钩子的问题,需要的朋友可以参考下
    2021-10-10
  • 五分钟带你快速学习Spring IOC

    五分钟带你快速学习Spring IOC

    这篇文章主要给大家介绍了关于如何通过五分钟快速学习Spring IOC的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-03-03
  • 详解Java解析XML的四种方法

    详解Java解析XML的四种方法

    本篇文章主要介绍了java解析XML的几种方式,XML现在已经成为一种通用的数据交换格式,给数据集成与交互提供了方便,有需要的可以了解一下。
    2016-11-11
  • SpringBoot 自动装配的原理详解分析

    SpringBoot 自动装配的原理详解分析

    这篇文章主要介绍了SpringBoot 自动装配的原理详解分析,文章通过通过一个案例来看一下自动装配的效果展开详情,感兴趣的小伙伴可以参考一下
    2022-08-08
  • 解析Java格式字符串的使用

    解析Java格式字符串的使用

    本文通过实例给大家介绍了java格式字符串的使用,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2022-02-02
  • RabbitMQ幂等性与优先级及惰性详细全面讲解

    RabbitMQ幂等性与优先级及惰性详细全面讲解

    关于MQ消费者的幂等性问题,在于MQ的重试机制,因为网络原因或客户端延迟消费导致重复消费。使用MQ重试机制需要注意的事项以及如何解决消费者幂等性与优先级及惰性问题以下将逐一讲解
    2022-11-11
  • AsyncHttpClient的默认配置源码流程解读

    AsyncHttpClient的默认配置源码流程解读

    这篇文章主要为大家介绍了AsyncHttpClient的默认配置源码流程解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • SpringBoot配置log4j2的实现示例

    SpringBoot配置log4j2的实现示例

    SpringBoot中默认使用Logback作为日志框架,本文主要介绍了SpringBoot配置log4j2的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Mockito 结合 Springboot 进行应用测试的方法详解

    Mockito 结合 Springboot 进行应用测试的方法详解

    这篇文章主要介绍了Mockito 结合 Springboot 进行应用测试的方法详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11

最新评论