RuoYi模块功能分析:第七章分页实现及mybatis分页插件实现原理

文章目录

  • 一、依赖
  • 二、若依的使用
    • 2.1、PageUtils工具类
    • 2.2、SQL注入


一、依赖


<dependency>
    <groupId>com.github.pagehelpergroupId>
    <artifactId>pagehelper-spring-boot-starterartifactId>
dependency>

二、若依的使用

 @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
 @GetMapping("/list")
 public TableDataInfo list(SysOperLog operLog)
 {
 	 // BaseController下封装的方法
     startPage();
     List<SysOperLog> list = operLogService.selectOperLogList(operLog);
     return getDataTable(list);
 }

2.1、PageUtils工具类

位于package com.ruoyi.common.utils;包下

/**
 * 分页工具类
 * 
 * @author ruoyi
 */
public class PageUtils extends PageHelper
{
    /**
     * 设置请求分页数据
     */
    public static void startPage()
    {
        // 通过request获取分页请求参数并且设置默认值
        PageDomain pageDomain = TableSupport.buildPageRequest();

        // 获取分页参数
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        Boolean reasonable = pageDomain.getReasonable();
        
        // 防止sql注入
        String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());

        /**
         * 设置分页参数,分页插件会在当前线程中添加分页参数/在执行的sql中自动拼接分页参数。完成后会自动清除分页参数
         */
        PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
    }

    /**
     * 清理分页的线程变量
     */
    public static void clearPage()
    {
        PageHelper.clearPage();
    }
}

2.2、SQL注入

在有些需求下,我们需要用${}来进行sql拼接这样就会导致用户可以会对请求参数进行拼接sql,对数据库进行破坏。这个时候我们就需要对请求参数进行校验

/**
 * sql操作工具类
 * 
 * @author ruoyi
 */
public class SqlUtil
{
    /**
     * 定义常用的 sql关键字。
     */
    public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()";

    /**
     * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
     */
    public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";

    /**
     * 限制orderBy最大长度
     */
    private static final int ORDER_BY_MAX_LENGTH = 500;

    /**
     * 检查字符,防止注入绕过
     */
    public static String  escapeOrderBySql(String value)
    {
        if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
        {
            throw new UtilException("参数不符合规范,不能进行查询");
        }
        if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
        {
            throw new UtilException("参数已超过最大限制,不能进行查询");
        }
        return value;
    }

    /**
     * 验证 order by 语法是否符合规范
     */
    public static boolean isValidOrderBySql(String value)
    {
        return value.matches(SQL_PATTERN);
    }

    /**
     * SQL关键字检查
     */
    public static void filterKeyword(String value)
    {
        if (StringUtils.isEmpty(value))
        {
            return;
        }
        String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
        for (String sqlKeyword : sqlKeywords)
        {
            if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
            {
                throw new UtilException("参数存在SQL注入风险");
            }
        }
    }
}

你可能感兴趣的:(Java开发专栏,windows,java)