Android SQLiteException: near "": syntax error (code 1) 错误 以及 防止Sql注入


一、写在前文

     已经很久没有写过博客了,第一次写博客是在2015年的时候,那时候第一次接触CSDN,感觉很新鲜,所以当时就写了好几篇博客,那会刚刚好学C++,所以写的都是关于C++的,而现在已经学习Android一年多了,心血来潮打开以前的文章,没想到竟然还有300多阅读量。而最近项目刚刚赶好,所以决定从新开始记录博客。


二、遇到的问题


       项目需求如下: 在搜索框输入关键字,进行模糊搜索,从数据库获取数据进行展示。
    
      于是开始着手写代码:简单实现如下:
        
// key 为搜索关键字 其他为自定义的数据库字段  group by 为分组查询
   String selection =
      Columns.ID   + " like " + "'%" + key + "%'" + " or " +
      Columns.NAME + " like " + "'%" + key + "%'" + " or " +
      Columns.NUM  + " like " + "'%" + key + "%'";

    Cursor cursor =
      context.getContentResolver().query(
        URI,
        null,
        selection + ") group by (key",
        null,
        null );

      上面代码相信大家平时已经司空见惯了,我一开始也没在意,测试了觉得没问题就提交了代码了,直到周末放假..... 
      测试使用魅蓝m2测试,发现 闪退!闪退!闪退! 吓得我赶紧去腾讯优测租用一台一样的测试机进行测试,不过还是没发现问 题。后来才发现是他输入的时候是用的九宫格输入法,输入hh的时候,搜索框会先输入h'h, 注意 h'h, 多了一个 ' 。报错信息如下:

        
 android.database.sqlite.SQLiteException: near "h": syntax error (code 1): , while compiling: 
  like '%h'h%'


       错误信息很显然,输入h‘h,输入法多出的 ' 和 我的sql语句拼接在一起,造成SQL的语法错误。同时,在这里我也忘记 加入 防止 SQL注入的策略,这是造成sql语法错误的原因之一。

 

二、解决问题

        
       一开始,我觉得的思路是替换掉 ' ,  于是对 搜索关键字 key 进行过滤处理如下: key = key.replaceAll(“'”,"");  确实也不会报错, 但是用户的搜索关键字是 ',你总不能强制过滤掉吧。于是上网搜索类似的问题,在谷歌开发者文档看到类似的说明,如下:
    Android SQLiteException: near
        读者也可以点击 谷歌官方使用文档  查看具体介绍。 

        文档大致意思就是使用 ? 占位符去代替关键字,这样就可以防止SQL注入。

        所以接下来我就更改了代码实现,如下:

     String selection =
        Columns.ID   + " like ?" + " or " +
        Columns.NAME + " like ?" + " or " +
        Columns.NUM  + " like ?";

     String []selectionArgs = {"%" + key + "%", "%" + key + "%", "%" + key + "%"};

     Cursor cursor =
      context.getContentResolver().query(
        URI,
        null,
        selection + ") group by (key",
        selectionArgs,
        null
     );

       通过使用上面的参数查询方式,就不用再害怕SQL的注入还有特殊字符的影响了。

       
      已经很久没有写过博客了,希望大家能够指出我的不足之处!

   
    


你可能感兴趣的:(Android)