我有一个插入语句,如下所示
private final COLUMNS = "NAME,TYPE,STATUS,CATEGORY";
String values = list
.stream()
.collect(Collectors.joining(","));
String insertStatement = String.format("INSERT INTO ifc.documents (%s) VALUES (%s) ",COLUMNS,values);
我可以轻松地将COLUMNS设置为不需要引号但是对于值,我的SQL失败并且抱怨上面的代码缺少引号。
所以,我试过
String values = list.stream()
.collect(Collectors.joining("','"));
但它也失败了。所以我做了一个解决方法,并添加了另一个语句前缀和后缀单引号,它开始工作。
values = "'"+values+"'";
更具体地说,如果我说"休息","测试"和#34;最好"在列表中
然后预期输出
'rest','test','best'
任何人都知道更好的解决方案吗?
答案 0 :(得分:14)
您实际上可以使用Collectors.joining(CharSequence delimiter,CharSequence prefix,CharSequence suffix)
,并且可以查看here的API。
String values = list.stream().collect(Collectors.joining("','", "'", "'"));
答案 1 :(得分:6)
您可以使用带有前缀和后缀参数的overload of Collectors.joining
。
String values = list.stream()
.collect(Collectors.joining("','", "'", "'"));
这将正确地在所有值周围放置单引号,假设您的所有值都是需要单引号用于语法的字符串。
但是,与涉及通过连接值构建查询的所有问题一样,它使您容易受到SQL注入的影响。更安全,更通用的解决方案涉及使用PreparedStatement
。值占位符为?
个字符,您可以使用各种setXyz
方法安全地设置值。它可以防止SQL注入,并允许使用任何数据类型,而不仅仅是字符串类型。
答案 2 :(得分:4)
不要构建价值观'部分使用字符串连接,因为它为SQL注入攻击提供了可能性。
我在这里使用准备好的声明。您仍然可以像这样构建您的请求:
ggplot(data = df1, aes(x=x, y=val)) + geom_line(aes(colour=variable))
然后将List<String> columns = Arrays.asList("column1", "column2", "column3");
String columnsFragment = columns.stream().collect(Collectors.joining(","));
String placeholdersFragment = columns.stream().filter(s -> "?").collect(Collectors.joining(","))
String insertStatement = String.format("INSERT INTO ifc.documents (%s) VALUES (%s) ", columnsFragment, placeholdersFragment);
与insertStatement
:
PreparedStatement
在这种情况下,生成的查询看起来像
PreparedStatement st = connection.prepareStatement(insertStatement);
for (int i = 0; i < values.size(); i++) {
// +1 because prepared statement parameters indices are 1-based
st.setString(i + 1, values.get(i));
}
st.executeUpdate();
答案 3 :(得分:1)
使用String.join方法的另一种解决方案,就像这样
String result = "'"+String.join("','", list)+"'";
Function<List<String>,String> function = list2->"'".concat(String.join("','",list2)).concat("'");
System.out.println(function.apply(list));
或使用reduction喜欢这个
String result = "'"+list.stream().reduce((s, p) -> s + "','" + p).get()+"'";