SQL保留字符的处理(like,%,_) -Android下Java层的处理

上一篇从SQL的角度看了一下like保留字符和转义字符的解决方法。在Android平台下,一般是在Java层根据业务逻辑拼装SQL语句。所以需要对于like参数做转义字符的替换,然后再将后缀escape代码段拼接上去。对于转义字符的替换,有2点需要注意:

(1)对于你作为转义字符的字符本身,不要忘记在前面需要再增加一个转义字符,否则会出现错误。举如下例子

sqlite> select * from test_table;
id|name|description
0|name0|des0
1|name1|des1
2|_|%
3|a|b
4|_d|%d
5|tr|%u
6|_aa|yy
7|xyz|
8|abc%90|zz
9|abcdefg|888
10|bc%90|00

在这个table中查询name以abc%开头的数据,其中%是字面量本身。显然不能直接将abc%作为参数拼接,会得到如下错误结果:

sqlite> select * from test_table where name like 'abc%%';
id|name|description
8|abc%90|zz
9|abcdefg|888

假设我们想用a作为转义字符,但没有处理a本身,select结果错误:

sqlite> select * from test_table where name like 'abca%%' escape 'a';
id|name|description
10|bc%90|00

原因是第一个a被识别成转义字符,ab也就是转义b,b本身并非保留字符,转义之后仍然是b。拼接之后等同于select以bc%开头的name。
正确的方式是:

sqlite> select * from test_table where name like 'aabca%%' escape 'a';
id|name|description
8|abc%90|zz

(2)转义字符的替换是类似将%转成/%,即在Java字符串中将一个字符替换成两个字符,这样的话,使用String.replace()不如使用StringBuilder去逐个字符处理更合适,因为String.replace()需要将单个字符也转成字符串,另外有多个保留字符需要处理,所以String.replace()会有很多中间结果字符串。用一段代码来测试:

                Log.i("TEST", "start test");
                long now = System.currentTimeMillis();

                for (int i = 0 ; i < 100000 ; i++) {
                    "abc%defghijk_lmnopq/rstuvwxyz"
                            .replace("/", "//")
                            .replace("%", "/%%")
                            .replace("_", "/_");
                }

                Log.i("TEST", "1 : " + (System.currentTimeMillis() - now));

                now = System.currentTimeMillis();

                for (int i = 0 ; i < 100000 ; i++) {
                    String s = "abc%defghijk_lmnopq/rstuvwxyz";
                    StringBuilder sb = new StringBuilder();
                    char c;

                    for (int j = 0; j < s.length(); j++) {
                        c = s.charAt(j);
                        if (c == '/' || c == '%' || c == '_') {
                            sb.append('/');
                        }
                        sb.append(c);
                    }
                }
                Log.i("TEST", "2 : " + (System.currentTimeMillis() - now));

结果:

10-25 09:38:17.488 32505 32546 I TEST    : start test
10-25 09:38:18.749 32505 32546 I TEST    : 1 : 1261
10-25 09:38:19.731 32505 32546 I TEST    : 2 : 982

看到StringBuilder还是有优势。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值