java 查询 hologres,对holo查询语句控制,防止个别任务执行卡死,影响其他的任务
这个方法可以直接拷贝使用,返回类型可以是List<Map<String, Object>>,也可以是Java类对象,也可以基础类型集合,注意:如果是Java对象,sql查询语句要对查询字段和类对象映射,如:
SELECT
us.alias_name AS aliasName
FROM
USER 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 {
@Resource
private 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;
}
}