java 查询 hologres,对holo查询语句控制,防止个别任务执行卡死,影响其他的任务
这个方法可以直接拷贝使用,返回类型可以是List<Map<String, Object>>,也可以是Java类对象,也可以基础类型集合,注意:如果是Java对象,sql查询语句要对查询字段和类对象映射,如:
SELECTus.alias_name AS aliasName
FROMUSER us
以下是util方法:
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.annotation.Resource;
import javax.sql.DataSource;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;/**** 支持Map<String, Object> 和 JAVA 类**/
@Slf4j
@Component
public class HologresUtils {@Resourceprivate DataSource hologresDataSource;/*** 查询* @param business 业务名称* @param sql 查询语句* @param clazz 结果类型* @param timeout 超时时间* @return 结果列表*/public <T> List<T> query(String business, String sql, Class<T> clazz, int timeout) {List<T> results = new ArrayList<>();Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {connection = hologresDataSource.getConnection();statement = connection.createStatement();statement.setQueryTimeout(timeout);resultSet = statement.executeQuery(sql);ResultSetMetaData metaData = resultSet.getMetaData();int columnCount = metaData.getColumnCount();if (columnCount == 1) {results = handleSingleColumnResult(resultSet, metaData, clazz);} else {results = handleMultiColumnResult(resultSet, clazz);}} catch (Exception e) {log.error(business + "holo查询异常,sql={}, error=", sql, e);cancelQuery(statement);} finally {closeResources(resultSet, statement, connection);}return results;}private <T> List<T> handleSingleColumnResult(ResultSet resultSet, ResultSetMetaData metaData, Class<T> clazz) throws SQLException {List<T> results = new ArrayList<>();String columnName = metaData.getColumnName(1);while (resultSet.next()) {Object value = extractValue(resultSet, columnName, clazz);@SuppressWarnings("unchecked")T castedValue = (T) value;results.add(castedValue);}return results;}private <T> List<T> handleMultiColumnResult(ResultSet resultSet, Class<T> clazz) throws Exception {List<T> results = new ArrayList<>();if (Map.class.isAssignableFrom(clazz)) {@SuppressWarnings("unchecked")List<T> mapResults = (List<T>) queryAsMap(resultSet);results.addAll(mapResults);} else {Field[] fields = clazz.getDeclaredFields();Map<String, Field> fieldMap = new HashMap<>();for (Field field : fields) {fieldMap.put(field.getName(), field);field.setAccessible(true);}while (resultSet.next()) {T instance = clazz.getDeclaredConstructor().newInstance();for (Map.Entry<String, Field> entry : fieldMap.entrySet()) {String fieldName = entry.getKey();Field field = entry.getValue();Object value = extractValue(resultSet, fieldName, field.getType());field.set(instance, value);}results.add(instance);}}return results;}private Object extractValue(ResultSet resultSet, String columnName, Class<?> fieldType) throws SQLException {Object value;if (fieldType == String.class) {value = resultSet.getString(columnName);} else if (fieldType == Integer.class || fieldType == int.class) {value = resultSet.getInt(columnName);} else if (fieldType == Long.class || fieldType == long.class) {value = resultSet.getLong(columnName);} else if (fieldType == Double.class || fieldType == double.class) {value = resultSet.getDouble(columnName);} else if (fieldType == Boolean.class || fieldType == boolean.class) {value = resultSet.getBoolean(columnName);} else if (fieldType == Date.class) {value = resultSet.getDate(columnName);} else if (fieldType == Timestamp.class) {value = resultSet.getTimestamp(columnName);} else {log.error("类型不匹配");return null;}return value;}private void cancelQuery(Statement statement) {if (statement != null) {try {statement.cancel();} catch (SQLException e) {log.error("holo取消查询异常,error={}", e.getMessage());}}}private void closeResources(ResultSet resultSet, Statement statement, Connection connection) {try {if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException ignored) {}}private List<Map<String, Object>> queryAsMap(ResultSet resultSet) throws SQLException {List<Map<String, Object>> results = new ArrayList<>();ResultSetMetaData metaData = resultSet.getMetaData();int columnCount = metaData.getColumnCount();while (resultSet.next()) {Map<String, Object> row = new HashMap<>();for (int i = 1; i <= columnCount; i++) {String columnName = metaData.getColumnName(i);Object value = resultSet.getObject(i);row.put(columnName, value);}results.add(row);}return results;}
}