Para ser honesto, JdbcTemplate
no es la mejor opción para este tipo de tarea. Tendrá que hacer un procesamiento por única vez del ResultSet
para crear el SQL insertado y realmente no hay ningún punto en el que pueda hacerlo usando JdbcTemplate
(hasta donde yo sé).
De todos modos, esta es la forma en que lo haría la copia que desea en el más puro JDBC (se puede tomar los mismos principios y meterla en JdbcTemplate
si quieres):
Connection sourceConnection = null;
Connection destinationConnection = null;
PreparedStatement selectStatement = null;
PreparedStatement insertStatement = null;
ResultSet resultSet = null;
try
{
sourceConnection = ...
destinationConnection = ...
selectStatement = sourceConnection.prepareStatement("SELECT * FROM table");
resultSet = selectStatement.executeQuery();
insertStatement = destinationConnection.prepareStatement(createInsertSql(resultSet.getMetaData()));
int batchSize = 0;
while (resultSet.next())
{
setParameters(insertStatement, resultSet);
insertStatement.addBatch();
batchSize++;
if (batchSize >= BATCH_EXECUTE_SIZE)
{
insertStatement.executeBatch();
batchSize = 0;
}
}
insertStatement.executeBatch();
}
finally
{
JdbcUtils.closeResultSet(resultSet);
JdbcUtils.closeStatement(insertStatement);
JdbcUtils.closeStatement(selectStatement);
JdbcUtils.closeConnection(destinationConnection);
JdbcUtils.closeConnection(sourceConnection);
}
El bit es lo importante ocurre en los métodos createInsertSql
y setParameters
, que usan el ResultSetMetaData
para realizar sus operaciones. Tendrá que jugar con ellos un poco dependiendo de la base de datos que está utilizando, pero se van a ver algo como:
private String createInsertSql(ResultSetMetaData resultSetMetaData) throws SQLException
{
StringBuffer insertSql = new StringBuffer("INSERT INTO ");
StringBuffer values = new StringBuffer(" VALUES (");
insertSql.append(resultSetMetaData.getTableName());
for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++)
{
insertSql.append(resultSetMetaData.getColumnName(i));
values.append("?");
if (i <= resultSetMetaData.getColumnCount())
{
insertSql.append(", ");
values.append(", ");
}
else
{
insertSql.append(")");
values.append(")");
}
}
return insertSql.toString() + values.toString();
}
Y:
private void setParameters(PreparedStatement preparedStatement, ResultSet resultSet) throws SQLException
{
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++)
{
preparedStatement.setObject(i, resultSet.getObject(i));
}
}
Nota Esto sólo funciona si la fuente y las bases de datos de destino tienen tablas estructuradas de manera idéntica. Si varían, tendrá que comenzar a definir las asignaciones entre los dos, y en ese momento es mejor que simplemente compre una herramienta de ETL.
siguiente comentario
La inserción/actualización cosa es mucho más difícil.
Desde el DatabaseMetaData
necesitaría obtener la clave principal y consultar las tablas de origen y de destino asegurándose de que la consulta ordene por las columnas de la clave principal.
Luego, al iterar sobre el conjunto de resultados de origen, deberá verificar el conjunto de resultados de destino para ver si las columnas de claves principales coinciden o son mayores en el pedido, creando insertar o actualizar sql de manera correspondiente.
Por ejemplo, si tiene teclas de enteros simples en la tabla de origen 1, 2, 3, 4, 7 y en la tabla de destino que tenía 1, 2, 4, 5, 6 a continuación:
- 1 = actualizar
- 2 = actualización
- 3 porque es antes de las 4 puede ser de forma segura una inserción
- 4 = actualización
- 7 que necesita para recorrer el conjunto de resultados de destino hasta que haya pasado el pasado 6 antes de poder saber con certeza que 7 es un inserto.
Lo siento si no está tan claro, es difícil de explicar en texto estático.
Defina lo que quiere decir con "tablas similares": ¿tienen la misma estructura y la única diferencia es la base de datos en la que se encuentran o la estructura difiere? –
Misma estructura. Por ejemplo, tengo las tablas A, B, C en DB1, que tienen una estructura diferente, y necesito archivar estas tablas en DB2, que tiene las tablas A, B y C. – vikknp