我正在尝试编写java代码,我想在其中形成一个像“select * from ABC where DIFFERENT CONDITIONS”这样的语句
示例1
名字 | 价值观 |
---|---|
DATE_START | 0 |
DATE_END | 20230101 |
TIME_START | 0 |
TIME_END | 173000 |
所以在这个例子中应该是 “从 ABC 中选择 *,其中“0”和“20230101”之间的日期以及“0”和“173000”之间的时间;”
示例2
名字 | 价值观 |
---|---|
DATE_START | 0 |
DATE_END | 20230101 |
TIME_START | 0 |
TIME_END | 173000 |
第一年 | 2015 |
第二年 | 2016 |
ACDAT_START | 20200101 |
ACDAT_END | 20200202 |
所以在这个例子中应该是
“从 ABC 中选择 *,其中“0”和“20230101”之间的日期和“0”和“173000”之间的时间以及“2015”中的第一年和“2016”中的第二年以及“20200101”和“20200101”之间的 ACDAT ; “
请建议如何编写java代码来动态传递值并从名称中获取某些前缀。
将参数放入映射中
Map<String, String>
并使用下划线 (_
) 之前的子字符串对它们进行分组,并获得 Map<String, Map<String, String>>
。流式传输分组的地图并添加子句,检查是否有任何键以 _START
或 _END
结尾。由于标准映射不允许重复的键,因此如果您的 YEAR1
或 YEAR2
参数可以有多个值,请将它们添加为逗号分隔值。示例:
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public class Example {
public static void main(String[] args) {
Map<String, String> paramsExample1 = Map.of("DATE_START", "0",
"DATE_END", "20230101",
"TIME_START", "0",
"TIME_END", "173000",
"YEAR1", "2015",
"YEAR2", "2016",
"ACDAT_START", "20200101",
"ACDAT_END", "20200202" );
Map<String, String> paramsExample2 = Map.of("DATE_START", "0",
"DATE_END", "20230101",
"TIME_START", "0",
"TIME_END", "173000");
Map<String, String> paramsExample3 = Map.of("DATE_START", "0",
"DATE_END", "20230101",
"TIME_START", "0",
"TIME_END", "173000",
"YEAR1", "2015, 2016, 2017",
"YEAR2", "2016, 2019");
System.out.println(createQuery(paramsExample1));
System.out.println(createQuery(paramsExample2));
System.out.println(createQuery(paramsExample3));
}
private static String createQuery(final Map<String, String> params) {
return "SELECT * FROM ABC WHERE " +
params.entrySet()
.stream()
.collect(Collectors.groupingBy(e -> e.getKey().split("_" )[0],
Collectors.toMap(Entry::getKey, Entry::getValue)))
.entrySet()
.stream()
.map(e -> addClause(e)).collect(Collectors.joining(" AND " )) + ';';
}
private static String addClause(Entry<String, Map<String, String>> e) {
return e.getValue().keySet().stream().anyMatch(k -> k.endsWith("_START" )) ?
e.getKey() + " BETWEEN '" + e.getValue().get(e.getKey() + "_START" ) + "' AND '" + e.getValue().get(
e.getKey() + "_END" ) + '\'' :
e.getKey() + " IN (" + e.getValue().get(e.getKey()) + ")";
}
}