BoundSql.java 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package org.ssssssss.magicapi.functions;
  2. import org.ssssssss.magicapi.cache.SqlCache;
  3. import org.ssssssss.script.MagicScriptContext;
  4. import org.ssssssss.script.functions.StreamExtension;
  5. import org.ssssssss.script.parsing.GenericTokenParser;
  6. import org.ssssssss.script.parsing.ast.literal.BooleanLiteral;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import java.util.Optional;
  10. import java.util.concurrent.atomic.AtomicBoolean;
  11. import java.util.regex.Pattern;
  12. public class BoundSql {
  13. private static final GenericTokenParser concatTokenParser = new GenericTokenParser("${", "}", false);
  14. private static final GenericTokenParser replaceTokenParser = new GenericTokenParser("#{", "}", true);
  15. private static final GenericTokenParser ifTokenParser = new GenericTokenParser("?{", "}", true);
  16. private static final GenericTokenParser ifParamTokenParser = new GenericTokenParser("?{", ",", true);
  17. private static final Pattern REPLACE_MULTI_WHITE_LINE = Pattern.compile("(\r?\n(\\s*\r?\n)+)");
  18. private String sql;
  19. private List<Object> parameters = new ArrayList<>();
  20. private String cacheKey;
  21. BoundSql(String sql) {
  22. MagicScriptContext context = MagicScriptContext.get();
  23. // 处理?{}参数
  24. this.sql = ifTokenParser.parse(sql.trim(), text -> {
  25. AtomicBoolean ifTrue = new AtomicBoolean(false);
  26. String val = ifParamTokenParser.parse("?{" + text, param -> {
  27. ifTrue.set(BooleanLiteral.isTrue(context.eval(param)));
  28. return null;
  29. });
  30. if (ifTrue.get()) {
  31. return val;
  32. }
  33. return "";
  34. });
  35. // 处理${}参数
  36. this.sql = concatTokenParser.parse(this.sql, text -> String.valueOf(context.eval(text)));
  37. // 处理#{}参数
  38. this.sql = replaceTokenParser.parse(this.sql, text -> {
  39. Object value = context.eval(text);
  40. try {
  41. //对集合自动展开
  42. List<Object> objects = StreamExtension.arrayLikeToList(value);
  43. StringBuilder sb = new StringBuilder();
  44. for (int i = 0, size = objects.size(); i < size; i++) {
  45. sb.append("?");
  46. if (i + 1 < size) {
  47. sb.append(",");
  48. }
  49. parameters.add(objects.get(i));
  50. }
  51. return sb.toString();
  52. } catch (Exception e) {
  53. parameters.add(value);
  54. return "?";
  55. }
  56. });
  57. this.sql = this.sql == null ? null : REPLACE_MULTI_WHITE_LINE.matcher(this.sql.trim()).replaceAll("\r\n");
  58. }
  59. /**
  60. * 添加SQL参数
  61. */
  62. public void addParameter(Object value) {
  63. parameters.add(value);
  64. }
  65. /**
  66. * 获取要执行的SQL
  67. */
  68. public String getSql() {
  69. return sql;
  70. }
  71. /**
  72. * 获取要执行的参数
  73. */
  74. public Object[] getParameters() {
  75. return parameters.toArray();
  76. }
  77. /**
  78. * 清空缓存key
  79. */
  80. public BoundSql removeCacheKey() {
  81. this.cacheKey = null;
  82. return this;
  83. }
  84. /**
  85. * 获取缓存key
  86. */
  87. public String getCacheKey(SqlCache sqlCache) {
  88. if (cacheKey == null) {
  89. cacheKey = sqlCache.buildSqlCacheKey(this);
  90. }
  91. return cacheKey;
  92. }
  93. /**
  94. * 获取缓存值
  95. */
  96. public <T> Optional<T> getCacheValue(SqlCache sqlCache, String cacheName) {
  97. return Optional.ofNullable(cacheName == null ? null : sqlCache.get(cacheName, getCacheKey(sqlCache)));
  98. }
  99. }