如何通过','加入列表元素使用'作为前缀和后缀

时间:2018-02-23 18:59:21

标签: java java-8 java-stream

我有一个插入语句,如下所示

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'

任何人都知道更好的解决方案吗?

4 个答案:

答案 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()+"'";