package com.vcarecity.cvs.service.impl; import com.vcarecity.cvs.core.AutoMapper; import com.vcarecity.cvs.service.SQLQueryService; import com.zaxxer.hikari.HikariDataSource; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import static com.vcarecity.cvs.FileExporterApp.TABLE_COLUMN; /** * @author Kerry on 19/11/27 */ @Slf4j public abstract class AbstractSQLQueryService implements SQLQueryService { private boolean isFirst = true; protected final HikariDataSource dataSource; protected AbstractSQLQueryService(HikariDataSource dataSource) { this.dataSource = dataSource; } @Override public List queryByPage(String table, int page, int pageCount, Class clazz) throws SQLException { final String querySql = getQuerySql(table); long startTime = System.currentTimeMillis(); final Connection connection = dataSource.getConnection(); final PreparedStatement preparedStatement = getPreparedStatement(connection, querySql, page, pageCount); ResultSet resultSet = preparedStatement.executeQuery(); List list = resultMapper(table, resultSet, clazz); logger.debug("query success. size = {}. usageTime = {} /ms", list.size(), (System.currentTimeMillis() - startTime)); resultSet.close(); preparedStatement.close(); connection.close(); return list; } /** * 组装表 * * @param table * @return */ protected abstract String getQuerySql(String table); /** * get PreparedStatement * * @param connection * @param sql * @param start * @param pageCount * @return * @throws SQLException */ protected abstract PreparedStatement getPreparedStatement(Connection connection, String sql, int start, int pageCount) throws SQLException; public List resultMapper(String table, ResultSet resultSet, Class clazz) throws SQLException { if (clazz == Object.class) { //noinspection unchecked return (List) resultSetToObject(table, resultSet); } return autoMapper(resultSet, clazz); } public List resultSetToObject(String table, ResultSet resultSet) throws SQLException { final ResultSetMetaData metaData = resultSet.getMetaData(); final int columnCount = metaData.getColumnCount() - 1; final List columnWithObject = getColumnWithObject(metaData); final Set skipIndex = columnWithObject.stream().map(ColumnIndexName::getIndex).collect(Collectors.toSet()); final String[] header = columnWithObject.stream().map(ColumnIndexName::getName).toArray(String[]::new); TABLE_COLUMN.put(table, header); if (isFirst) { final String join = String.join(",", header); logger.info("header = ({})", join); isFirst = false; } List data = new ArrayList<>(); while (resultSet.next()) { Object[] objects = new Object[columnCount]; int cIndex = 0; for (int i = 0; i < columnCount; i++) { if (!skipIndex.contains(i)) { continue; } objects[cIndex++] = resultSet.getObject(i + 1); } data.add(objects); } return data; } @NoArgsConstructor @AllArgsConstructor @Data public static class ColumnIndexName { private int index; private String name; } /** * @param metaData * @return */ protected List getColumnWithObject(ResultSetMetaData metaData) throws SQLException { final int columnCount = metaData.getColumnCount(); List res = new ArrayList<>(columnCount); for (int i = 0; i < columnCount; i++) { String name = metaData.getColumnName(i + 1); res.add(new ColumnIndexName(i, name)); } return res; } public List autoMapper(ResultSet resultSet, Class clazz) throws SQLException { List list = new ArrayList<>(); while (resultSet.next()) { final T t = AutoMapper.autoMapper(resultSet, clazz); if (t != null) { list.add(t); } } return list; } }