說實話,JdbcTemplate
不是這類任務的最佳選擇。您需要對ResultSet
進行一次性處理以創建插入SQL,並且使用JdbcTemplate
(據我所知)沒有任何意義。
無論如何,這是我怎麼會做你想要的副本純JDBC(你可以採取同樣的原則,並擠入JdbcTemplate
如果你想):
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);
}
最重要的一點是什麼發生在createInsertSql
和setParameters
方法中,這兩種方法都使用ResultSetMetaData
來執行其操作。你需要與這些有點取決於數據庫您使用的玩,但他們會是這個樣子:
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();
}
和:
private void setParameters(PreparedStatement preparedStatement, ResultSet resultSet) throws SQLException
{
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++)
{
preparedStatement.setObject(i, resultSet.getObject(i));
}
}
注意這隻能如果源和目標數據庫具有相同結構的表。如果它們發生變化,您必須開始定義兩者之間的映射關係,此時您最好購買ETL工具。
如下評論
插入/更新的東西是相當多的困難。
從DatabaseMetaData
您需要獲取主鍵並查詢源表和目標表,確保查詢按主鍵列排序。
然後,當您迭代源結果集時,您需要檢查目標結果集以查看主鍵列是否匹配或更大的排序順序,從而創建插入或更新SQL。
例如,如果你有在源表1,2,3,4,第7和在你有1,2,4,5,6則目標表簡單整數鍵:
- 1 =更新
- 2 =更新
- 3,因爲這4之前是可以安全地插入
- 4 =更新
需要迭代目標的結果集,直到你已經走過去的6就可以知道前
- 7確定7是插入。
對不起,如果不那麼清楚,很難在靜態文本中解釋。
請定義您通過「類似的表」的意思 - 難道它們具有相同的結構,唯一不同的是他們在或根本的結構不同的數據庫? –
同樣的結構。對於如我有表A,B,C中DB1它們都具有不同的結構,我需要這些表歸檔到DB2具有表A,B和C – vikknp