SQL字符串拼接最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class DbUtils {
private static final String PLACEHOLDER_PATTERN = "\\$\\{(.+?)\\}";

public static String replace(String source, Object object, Class<?> clazz) {
Pattern pattern = Pattern.compile(PLACEHOLDER_PATTERN);
Matcher matcher = pattern.matcher(source);

StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String placeholder = matcher.group();
String fieldName = matcher.group(1);
String value = getFieldValue(object, fieldName, clazz);
value = escapeSQL(value);
if (value != null) {
matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
} else {
matcher.appendReplacement(sb, Matcher.quoteReplacement(placeholder));
}
}
matcher.appendTail(sb);

return sb.toString();
}

public static String replace(String source, Map<String,String> map) {
Pattern pattern = Pattern.compile(PLACEHOLDER_PATTERN);
Matcher matcher = pattern.matcher(source);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String placeholder = matcher.group();
String key = matcher.group(1);
String value = map.get(key);
value = escapeSQL(value);
if (value != null) {
matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
} else {
matcher.appendReplacement(sb, Matcher.quoteReplacement(placeholder));
}
}
matcher.appendTail(sb);

return sb.toString();
}

public static Map<String, String> createMap(String... args){
Map<String,String> map = new HashMap<>();
for(int i = 0; i < args.length; i+= 2){
String key = args[i];
String value = args[i + 1];
map.put(key, value);
}
return map;
}

// 自定义SQL转义避免SQL注入
private static String escapeSQL(String value) {
value = value.replace("'", "''"); // 单引号用双单引号替换
value = value.replace(";", ""); // 去掉分号
value = value.replace("%", "%%"); // 百分号替换为%%
value = value.replace("\\", "\\\\"); // 转义\字符
return value;
}

private static String getFieldValue(Object object, String fieldName, Class<?> clazz) {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(object);
return value != null ? value.toString() : null;
} catch (Exception e) {
return null;
}
}
}