zoukankan      html  css  js  c++  java
  • 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>

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    ubuntu下安装pip
    [算法]获得最短路径的Floyd与Dijkstra算法
    win2003终端服务授权
    Cookie 读取,解决中文乱码
    MOSS自动备份
    MOSS 开发收藏
    Private Protect Partial Internal Public 区别
    怎么设置OUTLOOK接收邮件时,网站邮箱的原始文件也保存着?
    正则表达式实战
    SQL Server 2005 数据库用户和登录帐户设置关链
  • 原文地址:https://www.cnblogs.com/zxhbk/p/13937658.html
Copyright © 2011-2022 走看看