Java 如何通过';连接列表元素';使用流与';作为前缀和后缀

Java 如何通过';连接列表元素';使用流与';作为前缀和后缀,java,java-8,java-stream,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); 我可以

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

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); 
我可以很容易地将列作为不需要引号的列,但是对于值,我的SQL失败并抱怨上面的代码缺少引号

所以,我试过了

 String values = list.stream()
.collect(Collectors.joining("','"));
但是这个也失败了,所以我做了一个变通方法,添加了另一个语句,在一个引号前加上前缀和后缀,它就开始工作了

 values = "'"+values+"'";
更具体地说,若我在列表中说“休息”、“测试”和“最佳”

那么预期的输出是

'rest','test','best'

有人知道更好的解决方案吗?

您可以实际使用
收集器。加入(CharSequence分隔符、CharSequence前缀、CharSequence后缀)
,您可以查找API

String values = list.stream().collect(Collectors.joining("','", "'", "'"));
可以使用接受前缀和后缀参数的

 String values = list.stream()
    .collect(Collectors.joining("','", "'", "'"));
这将在所有值周围正确地放置单引号,假设所有值都是需要单引号作为语法的字符串


但是,与所有涉及通过串联值构造查询的问题一样,它使您的SQL容易被注入。一个更安全、更通用的解决方案涉及使用。值占位符是
字符,您可以使用各种
setXyz
方法安全地设置值。它可以防止SQL注入,并允许使用任何数据类型,而不仅仅是字符串类型。

不要使用字符串连接构造“值”部分,因为这可能会导致SQL注入攻击

我会在这里使用事先准备好的声明。您仍然可以这样构造您的请求:

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);
在本例中,生成的查询如下所示

INSERT INTO ifc.documents (column1, column2, column3) VALUES (?, ?, ?)
另一种解决方法是使用类似这样的方法

String result = "'"+String.join("','", list)+"'";

 Function<List<String>,String> function = list2->"'".concat(String.join("','",list2)).concat("'");
 System.out.println(function.apply(list));
String result =   "'"+list.stream().reduce((s, p) -> s + "','" + p).get()+"'";

您的输入和期望的输出是什么?您遇到了什么错误?您的问题不是如何使用逗号连接,而是如何引用值。请相应地编辑您的问题。与其使用流式处理,为什么不使用plane old for loop来构建值?
收集器。加入(“,”,“,”,“”)”)
会满足您的要求。但对于SQL来说,这不是一种安全的数据转义方法@亨利编辑!它仅在端到端测试框架中需要,我必须使用本机驱动程序,因此我对此很满意,但同意SQLInjection point。
String.join(delimiter,list)
比本问题中介绍的其他备选方案可读性好得多。
String result =   "'"+list.stream().reduce((s, p) -> s + "','" + p).get()+"'";