DataBase.java 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package com.scbfkj.uni.process;
  2. import com.fasterxml.jackson.databind.JsonNode;
  3. import com.scbfkj.uni.library.DataFormatUtil;
  4. import com.scbfkj.uni.library.DbUtil;
  5. import com.zaxxer.hikari.HikariConfig;
  6. import com.zaxxer.hikari.pool.HikariPool;
  7. import jakarta.annotation.Nonnull;
  8. import java.sql.Connection;
  9. import java.sql.PreparedStatement;
  10. import java.sql.ResultSet;
  11. import java.sql.SQLException;
  12. import java.util.*;
  13. import java.util.regex.Matcher;
  14. import java.util.regex.Pattern;
  15. import java.util.stream.Collectors;
  16. public class DataBase {
  17. public static List<Map<String, Object>> query(String connectionStr, String sql, List<Object[]> argsList) throws Exception {
  18. HikariPool dataSourcePool = getDataSourcePool(connectionStr);
  19. return argsList.parallelStream().flatMap(args -> {
  20. try (Connection connection = dataSourcePool.getConnection();
  21. PreparedStatement preparedStatement = connection.prepareStatement(sql)
  22. ) {
  23. for (int i = 0; i < args.length; i++) {
  24. preparedStatement.setObject(i + 1, args[i]);
  25. }
  26. ResultSet resultSet = preparedStatement.executeQuery();
  27. List<Map<String, Object>> result = DbUtil.getResult(connectionStr, sql, resultSet);
  28. return result.stream();
  29. } catch (Exception exception) {
  30. throw new RuntimeException("数据异常: %s\n sql: %s ;\n args: %s ".formatted(exception.getMessage(), sql, DataFormatUtil.toDate(args)));
  31. }
  32. }).toList();
  33. }
  34. public static int[] updateBatch(String connectionStr, String sql, List<Object[]> argsList) throws Exception {
  35. HikariPool dataSourcePool = getDataSourcePool(connectionStr);
  36. try (Connection connection = dataSourcePool.getConnection();
  37. PreparedStatement preparedStatement = connection.prepareStatement(sql)
  38. ) {
  39. int[] result = null;
  40. int index = 0;
  41. try {
  42. while (argsList.size() > index) {
  43. Object[] args = argsList.get(index);
  44. for (int i = 0; i < args.length; i++) {
  45. preparedStatement.setObject(i + 1, args[i]);
  46. }
  47. preparedStatement.addBatch();
  48. index++;
  49. }
  50. result = preparedStatement.executeBatch();
  51. connection.commit();
  52. } catch (SQLException e) {
  53. connection.rollback();
  54. throw new RuntimeException(e.getMessage());
  55. }
  56. return result;
  57. }
  58. }
  59. public static int exec(String connectionStr, String sql) throws Exception {
  60. HikariPool dataSourcePool = getDataSourcePool(connectionStr);
  61. try (Connection connection = dataSourcePool.getConnection();
  62. PreparedStatement preparedStatement = connection.prepareStatement(sql)
  63. ) {
  64. int i = preparedStatement.executeUpdate();
  65. try {
  66. connection.commit();
  67. } catch (Exception e) {
  68. connection.rollback();
  69. throw e;
  70. }
  71. return i;
  72. }
  73. }
  74. public static List<Map<String, Object>> query(String connectionStr, String sql, List<Map<String, Object>> argsList, List<String> filterColumns, Map<String, Object> filterLines) throws Exception {
  75. sql = sql.replaceAll("(\\r)?\\n", " ");
  76. if (Objects.nonNull(filterLines) && !filterLines.isEmpty()) {
  77. sql = " (%s %s %s) ".formatted(sql, sql.contains(" where ") ? " " : " where ", filterLines.entrySet().stream().map(it -> "%s = %s".formatted(it.getKey(), it.getValue())).collect(Collectors.joining(" and ")));
  78. }
  79. if (Objects.nonNull(filterColumns) && !filterColumns.isEmpty()) {
  80. sql = "select %s from %s".formatted(filterColumns.stream().collect(Collectors.joining(",")), sql);
  81. } else {
  82. sql = "select * from %s".formatted(sql);
  83. }
  84. List<List<Object>> result = new ArrayList<>();
  85. List<String> names = new ArrayList<>();
  86. if (sql.matches("《.*》")) {
  87. Pattern compile = Pattern.compile("(?=《).*(?=》)");
  88. Matcher matcher = compile.matcher(sql);
  89. int index = 0;
  90. while (matcher.find()) {
  91. String name = matcher.group(index);
  92. names.add(name);
  93. }
  94. }
  95. if (names.size() == 1 && names.contains("whereStr")) {
  96. List<Map<String, Object>> list = new ArrayList<>();
  97. for (Map<String, Object> stringObjectMap : argsList) {
  98. List<Object> args = new ArrayList<>();
  99. StringJoiner joiner = new StringJoiner(" and ");
  100. for (Map.Entry<String, Object> entry : stringObjectMap.entrySet()) {
  101. String formatted = "%s = ?".formatted(entry.getKey());
  102. args.add(entry.getValue());
  103. joiner.add(formatted);
  104. }
  105. String whereStr = " " + joiner;
  106. String sqlStr = sql.replace("《whereStr》", whereStr);
  107. List<Map<String, Object>> apply = query(connectionStr, sqlStr, new ArrayList<>() {{
  108. add(args.toArray());
  109. }});
  110. list.addAll(apply);
  111. }
  112. return list;
  113. } else {
  114. for (String it : names) {
  115. sql = sql.replace("《%s》".formatted(it), " ? ");
  116. }
  117. for (Map<String, Object> map : argsList) {
  118. List<Object> args = new ArrayList<>();
  119. for (String name : names) {
  120. args.add(map.get(name));
  121. }
  122. result.add(args);
  123. }
  124. return query(connectionStr, sql, result.stream().map(List::toArray).toList());
  125. }
  126. }
  127. private final static Map<String, HikariPool> dataSourcePools = new HashMap<>();
  128. private static HikariPool getDataSourcePool(String connectionStr) throws Exception {
  129. if (dataSourcePools.containsKey(connectionStr)) {
  130. return dataSourcePools.get(connectionStr);
  131. }
  132. JsonNode jsonNode = DataFormatUtil.stringToJsonNode(connectionStr);
  133. JsonNode jdbcUrl = jsonNode.get("jdbcUrl");
  134. JsonNode username = jsonNode.get("username");
  135. JsonNode password = jsonNode.get("password");
  136. JsonNode driverClassName = jsonNode.get("driverClassName");
  137. HikariPool dataSourcePool = createDataSourcePool(jdbcUrl.asText(), Objects.isNull(username) ? null : username.asText(), Objects.isNull(password) ? null : password.asText(), driverClassName.asText(), null);
  138. dataSourcePools.put(connectionStr, dataSourcePool);
  139. return dataSourcePool;
  140. }
  141. private static HikariPool createDataSourcePool(@Nonnull String url, String username, String password, String driver, String poolName) throws Exception {
  142. HikariConfig hikariConfig = new HikariConfig();
  143. hikariConfig.setMaximumPoolSize(Math.min(Runtime.getRuntime().availableProcessors(), 8));//最大核心数:当前可用CPU数,最大16
  144. hikariConfig.setKeepaliveTime(60000); //用于跟数据库保持心跳连接
  145. hikariConfig.setMaxLifetime(60000 * 60 * 4); //4小时 接在池中的最大生存时间,超过该时间强制逐出
  146. hikariConfig.addDataSourceProperty("cachePrepStmts", "true"); //是否自定义配置,为true时下面两个参数才生效
  147. hikariConfig.addDataSourceProperty("prepStmtCacheSize", "250"); //连接池大小默认25,官方推荐250-500
  148. hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); //单条语句最大长度默认256,官方推荐2048
  149. hikariConfig.addDataSourceProperty("useServerPrepStmts", "true"); //新版本MySQL支持服务器端准备,开启能够得到显著性能提升
  150. hikariConfig.addDataSourceProperty("useLocalSessionState", "true");
  151. hikariConfig.addDataSourceProperty("useLocalTransactionState", "true");
  152. hikariConfig.addDataSourceProperty("rewriteBatchedStatements", "true");//批量新增
  153. hikariConfig.addDataSourceProperty("cacheResultSetMetadata", "true");
  154. hikariConfig.addDataSourceProperty("cacheServerConfiguration", "true");
  155. hikariConfig.addDataSourceProperty("elideSetAutoCommits", "true");
  156. hikariConfig.addDataSourceProperty("maintainTimeStats", "false");
  157. hikariConfig.setJdbcUrl(url);
  158. if (Objects.nonNull(username)) {
  159. hikariConfig.setUsername(username);
  160. }
  161. if (Objects.nonNull(password)) {
  162. hikariConfig.setPassword(password);
  163. }
  164. if (Objects.nonNull(driver)) {
  165. hikariConfig.setDriverClassName(driver);
  166. }
  167. if (Objects.nonNull(poolName)) {
  168. hikariConfig.setPoolName(poolName);
  169. }
  170. hikariConfig.setAutoCommit(false);
  171. return new HikariPool(hikariConfig);
  172. }
  173. }