• Mybatis动态指定表名、列名,如何防止SQL注入?


    以下的代码,操作的是MySQL数据库

    方式一

    因为表名无法通过 CONCAT() 函数进行拼接,所以只能通过 ${} 直接将表名的字符串替换。

    <select id="selectUnionALL" resultType="Dept">
        SELECT * FROM ${tableName} WHERE deptno = #{deptno}
    </select>

    但是会存在SQL的注入,比如:tableName = dept_01; delete from dept_01; 就会删除所有的数据。

    解决方式:通过代码去判断传入的参数是否包含 delete、drop... 等危险操作。

    方式二

    假设存在数据库中存在 dept_01,dept_02,dept_03..... 这样命名的表,那么怎么做呢?

    可以通过存储过程去解决动态指定表名的问题。

    1)创建存储过程

    DROP PROCEDURE IF EXISTS getName;    -- 如果一创建存储过程则删除
    DELIMITER $$ -- 定义结束字符,可以任意
    -- 创建名称为getName的存储过程,需要传入的参数:tableName表名,deptno条件
    CREATE PROCEDURE getName(IN tableName VARCHAR(100), IN deptno INT)
    BEGIN
        DECLARE tn VARCHAR(10);    -- 创建变量保存表名
        set tn = 
        (    -- 查询MySQL中所有的表,然后根据 表所在的数据库 和 表的后缀名称 获取到对应的表名
            select table_name     
            from information_schema.TABLES 
            where table_schema='db03' 
                        AND table_name LIKE CONCAT('dept_', '%')
                        AND table_name LIKE CONCAT('%', tableName)
        );
        -- 再拼接查询语句
        set @sqlStr = CONCAT("SELECT * FROM ", tn," WHERE deptno = '", deptno, "'");
        PREPARE sqlStr FROM @sqlStr;    
        EXECUTE sqlStr;    -- 执行
    END $$
    -- 传入参数:表名的后缀  部门id
    CALL getName('02', 5);    -- 测试

    测试结果,这样就不存在注入问题,因为表名被作为了条件。

    2)接口编写

    // Controller层
    @GetMapping("selectUnionALL/db03")
    @ResponseBody
    public List<Dept> selectUnionALL() {
        Dept dept = new Dept();
        dept.setDeptno(5L);
        dept.setTableName("02");
    
        return deptService.selectUnionALL(dept);
    }
    // service层
    public List<Dept> selectUnionALL(Dept dept) {
        return deptMapper.selectUnionALL(dept);
    }
    // mapper层
    List<Dept> selectUnionALL(Dept dept);

    3)mapper.xml 调用

    <!-- statementType: 需要设置为 CALLABLE -->
    <select id="selectUnionALL" resultType="Dept" statementType="CALLABLE">
        CALL getName(#{tableName}, #{deptno});
    </select>

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    php排序之冒泡排序
    php排序之快速排序
    php 获取某个月的周次信息
    php 获取目录下文件列表
    计算某个生日是哪个星座的算法
    小物件之radio单选列表
    小物件之select单选下拉列表
    ajax跨域问题
    微信开发第6章 通过accesstoken获取用户粉丝列表
    微信开发第5章 通过accesstoken获取用户基本信息并修改用户备注
  • 原文地址:https://www.cnblogs.com/zxhbk/p/13937658.html
Copyright © 2020-2023  润新知