private
class ResultSetIterator {
ResultSet resultSet;
Statement stmt =
null;
List<String> colNames;
Iterator<Map<String, Object>> rSetIterator;
public ResultSetIterator(String query) {
try {
Connection c = getConnection();
stmt = c.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(batchSize);
stmt.setMaxRows(maxRows);
LOG.debug("Executing SQL: " + query);
long start = System.currentTimeMillis();
if (stmt.execute(query)) {
resultSet = stmt.getResultSet();
}
LOG.trace("Time taken for sql :"
+ (System.currentTimeMillis() - start));
colNames = readFieldNames(resultSet.getMetaData());
}
catch (Exception e) {
wrapAndThrow(SEVERE, e, "Unable to execute query: " + query);
}
if (resultSet ==
null) {
rSetIterator =
new ArrayList<Map<String, Object>>().iterator();
return;
}
rSetIterator =
new Iterator<Map<String, Object>>() {
public
boolean hasNext() {
return hasnext();
}
public Map<String, Object> next() {
return getARow();
}
public
void remove() {
/*
do nothing
*/
}
};
}
private Iterator<Map<String, Object>> getIterator() {
return rSetIterator;
}
private Map<String, Object> getARow() {
if (resultSet ==
null)
return
null;
Map<String, Object> result =
new HashMap<String, Object>();
for (String colName : colNames) {
try {
if (!convertType) {
//
Use underlying database's type information
result.put(colName, resultSet.getObject(colName));
continue;
}
Integer type = fieldNameVsType.get(colName);
if (type ==
null)
type = Types.VARCHAR;
switch (type) {
case Types.INTEGER:
result.put(colName, resultSet.getInt(colName));
break;
case Types.FLOAT:
result.put(colName, resultSet.getFloat(colName));
break;
case Types.BIGINT:
result.put(colName, resultSet.getLong(colName));
break;
case Types.DOUBLE:
result.put(colName, resultSet.getDouble(colName));
break;
case Types.DATE:
result.put(colName, resultSet.getDate(colName));
break;
case Types.BOOLEAN:
result.put(colName, resultSet.getBoolean(colName));
break;
case Types.BLOB:
result.put(colName, resultSet.getBytes(colName));
break;
default:
result.put(colName, resultSet.getString(colName));
break;
}
}
catch (SQLException e) {
logError("Error reading data ", e);
wrapAndThrow(SEVERE, e, "Error reading data from database");
}
}
return result;
}
private
boolean hasnext() {
if (resultSet ==
null)
return
false;
try {
if (resultSet.next()) {
return
true;
}
else {
close();
return
false;
}
}
catch (SQLException e) {
close();
wrapAndThrow(SEVERE,e);
return
false;
}
}
private
void close() {
try {
if (resultSet !=
null)
resultSet.close();
if (stmt !=
null)
stmt.close();
}
catch (Exception e) {
logError("Exception while closing result set", e);
}
finally {
resultSet =
null;
stmt =
null;
}
}
}
private List<String> readFieldNames(ResultSetMetaData metaData)
throws SQLException {
List<String> colNames =
new ArrayList<String>();
int count = metaData.getColumnCount();
for (
int i = 0; i < count; i++) {
colNames.add(metaData.getColumnLabel(i + 1));
}
return colNames;
}
rSetIterator =
new Iterator<Map<String, Object>>() {
public
boolean hasNext() {
return hasnext();
}
public Map<String, Object> next() {
return getARow();
}
public
void remove() {
/*
do nothing
*/
}
};
网上推荐的采取类似分页的方式 读取数据然后添加到solr索引库的方式个人感觉比较拙劣,当我们采取编程的方式从数据库读取数据添加到solr索引库的时候可以参考这种方式,采取原始的JDBC数据访问方式,有时间我再贴出来分享。