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