gpt4 book ai didi

java - 使用 spring jdbctemplate 提取数据加载到不同的数据库中

转载 作者:搜寻专家 更新时间:2023-11-01 00:52:10 26 4
gpt4 key购买 nike

我需要从我的数据库中的一些随机表中提取数据,并插入到不同数据库中的类似表中。

我不清楚如何编写可以处理所有表的通用方法。

this.jdbcTemplate.query("select * from TableName", new RowMapper() {
@Override
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
while(resultSet.next()){
// Fetch data in a generic object for later updating in a different schema
}
return null; //To change body of implemented methods use File | Settings | File Templates.
}
});

最佳答案

老实说,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);
}

重要的一点是 createInsertSqlsetParameters 方法中发生的事情,它们都使用 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 = 更新
  • 7 您需要迭代目标结果集,直到您超过 6,然后才能确定 7 是一个插入。

抱歉,如果不是那么清楚,静态文本很难解释。

关于java - 使用 spring jdbctemplate 提取数据加载到不同的数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10446047/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com