Added batchQuery().
git-svn-id: https://samskivert.googlecode.com/svn/trunk@1852 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -22,6 +22,8 @@ package com.samskivert.jdbc;
|
|||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@@ -39,6 +41,17 @@ import com.samskivert.util.StringUtil;
|
|||||||
*/
|
*/
|
||||||
public class JDBCUtil
|
public class JDBCUtil
|
||||||
{
|
{
|
||||||
|
/** Used for {@link #batchQuery}. */
|
||||||
|
public interface BatchProcessor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Called for each row returned during our batch query. Do not advance
|
||||||
|
* the result set, simply query its values with the get methods.
|
||||||
|
*/
|
||||||
|
public void process (ResultSet row)
|
||||||
|
throws SQLException;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the supplied JDBC statement and gracefully handles being
|
* Closes the supplied JDBC statement and gracefully handles being
|
||||||
* passed null (by doing nothing).
|
* passed null (by doing nothing).
|
||||||
@@ -117,6 +130,63 @@ public class JDBCUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issues a query with a potentially large number of keys in batches.
|
||||||
|
* For example, you might have 10,000 ids that you wish to use in an "in"
|
||||||
|
* clause, but don't trust the database to be smart about optimizing that
|
||||||
|
* many keys, so instead you use batchQuery like so:
|
||||||
|
* <pre>
|
||||||
|
* Collection<Integer> keys = ...;
|
||||||
|
* String query = "select NAME from USERS where USER_ID in (#KEYS)";
|
||||||
|
* JDBCUtil.BatchProcessor proc = new JDBCUtil.BatchProcessor() {
|
||||||
|
* public void process (ResultSet row) {
|
||||||
|
* String name = rs.getString(1);
|
||||||
|
* // do whatever with name
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
* JDBCUtil.batchQuery(conn, query, keys, false, 500, proc);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param query the SQL query to run for each batch with the string
|
||||||
|
* <code>#KEYS#</code> in the place where the batch of keys should be
|
||||||
|
* substituted.
|
||||||
|
* @param escapeKeys if true, {@link #escape} will be called on each key to
|
||||||
|
* escape any dangerous characters and wrap the key in quotes.
|
||||||
|
* @param batchSize the number of keys at a time to substitute in for
|
||||||
|
* <code>#KEYS#</code>.
|
||||||
|
*/
|
||||||
|
public static void batchQuery (
|
||||||
|
Connection conn, String query, Collection<?> keys,
|
||||||
|
boolean escapeKeys, int batchSize, BatchProcessor processor)
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
try {
|
||||||
|
Iterator<?> itr = keys.iterator();
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
// group one batch of keys together
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
for (int ii = 0; ii < batchSize && itr.hasNext(); ii++) {
|
||||||
|
if (ii > 0) {
|
||||||
|
buf.append(",");
|
||||||
|
}
|
||||||
|
String key = String.valueOf(itr.next());
|
||||||
|
buf.append(escapeKeys ? escape(key) : key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// issue the query with that batch
|
||||||
|
String squery = query.replace("#KEYS#", buf.toString());
|
||||||
|
ResultSet rs = stmt.executeQuery(squery);
|
||||||
|
while (rs.next()) {
|
||||||
|
processor.process(rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
close(stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls <code>stmt.executeUpdate()</code> on the supplied statement
|
* Calls <code>stmt.executeUpdate()</code> on the supplied statement
|
||||||
* with the supplied query, checking to see that it returns the
|
* with the supplied query, checking to see that it returns the
|
||||||
|
|||||||
Reference in New Issue
Block a user