美文网首页
mybatis 的坑——java.sql.SQLExceptio

mybatis 的坑——java.sql.SQLExceptio

作者: 惠惠雨辰 | 来源:发表于2020-12-15 22:34 被阅读0次

    在一次修改动态拼接的表名的sql时,使用#{},一直报错,检查sql没有问题,最终发现,在<select>标签中有这么一个属性statementType="STATEMENT";

    statementType="STATEMENT" ,这个属性是不开启预编译,#{}是使用预编译的,导致,sql中的占位符?一直没有被传入的参数所替换掉,所有一直没有找到传入的参数。

    之前很多动态拼接表名或者字段名的,都是采用这个,然后入参必须全部是${}才不会报错,但是现在可以不用写这个属性了,默认的开启预处理,也能使用${}。

    ${} 和 #{}是可以并存的

    但是有一点要注意的是,使用${}的时候要注意防止sql注入的问题了

    如何防止sql注入?

    1.使用#{}一劳永逸,但是特殊的地方,像是表名,字段名就要是'${}'

    【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。

    2.使用正则表达式过滤传入的参数

    要引入的包:

    import java.util.regex.*;

    正则表达式:

    private String CHECKSQL = “^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$”;

    判断是否匹配:

    Pattern.matches(CHECKSQL,targerStr);

    下面是具体的正则表达式:

    检测SQL meta-characters的正则表达式 :

    /(\%27)|(\’)|(\-\-)|(\%23)|(#)/ix

    修正检测SQL meta-characters的正则表达式 :/((\%3D)|(=))[^\n]*((\%27)|(\’)|(\-\-)|(\%3B)|(:))/i

    典型的SQL 注入攻击的正则表达式 :/\w*((\%27)|(\’))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

    检测SQL注入,UNION查询关键字的正则表达式 :/((\%27)|(\’))union/ix(\%27)|(\’)

    检测MS SQL Server SQL注入攻击的正则表达式:

    /exec(\s|\+)+(s|x)p\w+/ix

    等等…..

    3.字符串过滤

    比较通用的一个方法:

    (||之间的参数可以根据自己程序的需要添加)

    public static boolean sql_inj(String str){

    String inj_str = "'|and|exec|insert|select|delete|update|

    count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";

    String inj_stra[] = split(inj_str,"|");

    for (int i=0 ; i &lt; inj_stra.length ; i++ ){

    if (str.indexOf(inj_stra[i])&gt;=0){

    return true;

    }

    }

    return false;

    }

    4. 确认每种数据的类型,比如是数字,数据库则必须使用int类型来存储

    5. 规定数据长度,能在一定程度上防止sql注入

    6. 严格限制数据库权限,能最大程度减少sql注入的危害

    7. 避免直接响应一些sql异常信息,sql发生异常后,自定义异常进行响应

    当然这些中最好的方式还是使用预编译。

    相关文章

      网友评论

          本文标题:mybatis 的坑——java.sql.SQLExceptio

          本文链接:https://www.haomeiwen.com/subject/fdsggktx.html