前言
写这篇文章的目的主要是为了自己做一个总结,以及分享给可能会有需要的朋友,
背景
最近在项目中遇到需要从客户方的数据库中查询单表数据,然后将查询到的所有数据同步新增到我方的数据库中。目前客户方该表数据大概有500-600万条左右,之前也是没有遇到过这么大数据量大一个同步,最后经过多次的代码修改最终确定了下面的这种方式
方案
客户的数据库是oracle 我方的数据库是达梦 首先通过分页查询分批次的从客户方数据库中查询数据,然后每1000条数据手动提交一次,具体代码如下
代码
try {
//本次查询数据开始下标
int countStart = 1;
//本次查询数据结束下标
int countEnd = 500000;
//声明数据库连接对象
Connection conn = null;
//声明数据库执行对象
PreparedStatement prep = null;
//声明结果集对象
ResultSet result = null;
//查询客户数据库表数据(我这里是分页每次只查询50w条数据)
String sql = "select * from (select rownum rn,* from COMPANY_IFIND where isvalid =1)" + " where rn<=" + countEnd + " and rn>=" + countStart;
//我方需要新增数据的表
String insetFormMain = "INSERT INTO formmain_1057820220717545 (ID,field0001,field0002,field0003,field0004,field0014,field0015,field0016,field0017,field0018,field0019,field0020,field0021,field0022,field0023,field0024,field0025,field0026,field0033,field0034,field0035,field0036,field0042,field0043,field0044,field0045,field0046,start_date) " + "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
//获取客户方数据库连接对象(oracle)
conn = JdbcUtil.getConnection();
//声明查询对象
prep = conn.prepareStatement(sql);
//执行sql
result = prep.executeQuery();
//如果结果不为空
if (result != null) {
boolean bl = true;
//统计当前新增条数(每1000条需要提交一次)
int count = 0;
// 创建本地数据库连接(创建我方的数据库连接 达梦)
Connection connLocal = JDBCAgent.getRawConnection();
// 关闭自动提交
connLocal.setAutoCommit(false);
// 声明 新增公司底表 执行对象
PreparedStatement main = connLocal.prepareStatement(insetFormMain);
//如果不是最后一页(默认是ture, 因为是分页查询,所以当查询到最后一页数据并同步完成时,bl=false 跳出整个新增数据循环)
while (bl) {
while (result.next()) {
long uuid = UUIDLong.longUUID();
main.setLong(1, uuid);
main.setString(2, result.getString("SEQ") == null ? "" : result.getString("SEQ"));
main.setString(3, result.getString("ORGID") == null ? "" : result.getString("ORGID"));
main.setString(4, result.getString("COM_NAME") == null ? "" : result.getString("COM_NAME"));
main.setString(5, result.getString("FULL_NAME") == null ? "" : result.getString("FULL_NAME"));
main.setString(6, result.getString("COM_TYPE") == null ? "" : result.getString("COM_TYPE"));
main.setString(7, result.getString("WEBSITE") == null ? "" : result.getString("WEBSITE"));
main.setString(8, result.getString("REGISTER_ADDRESS") == null ? "" : result.getString("REGISTER_ADDRESS"));
main.setString(9, result.getString("MAIN_BUSINESS") == null ? "" : result.getString("MAIN_BUSINESS"));
main.setString(10, result.getString("INDUSTRY") == null ? "" : result.getString("INDUSTRY"));
main.setString(11, result.getString("IS_SYNC_RELATION") == null ? "" : result.getString("IS_SYNC_RELATION"));
main.setString(12, result.getString("ISVALID") == null ? "" : result.getString("ISVALID"));
if (result.getString("UPDATED_AT") != null) {
main.setDate(13, java.sql.Date.valueOf(dateFormat.format(dateFormat.parse(result.getString("UPDATED_AT"))).trim()));
}
if (result.getString("CREATED_AT") != null) {
main.setDate(14, java.sql.Date.valueOf(dateFormat.format(dateFormat.parse(result.getString("CREATED_AT"))).trim()));
}
main.setString(15, result.getString("OPT_USER") == null ? "" : result.getString("OPT_USER"));
main.setString(16, result.getString("OPT_NAME") == null ? "" : result.getString("OPT_NAME"));
main.setString(17, result.getString("OPT_FULL_NAME") == null ? "" : result.getString("OPT_FULL_NAME"));
main.setString(18, result.getString("OPT_ALIAS_NAME") == null ? "" : result.getString("OPT_ALIAS_NAME"));
main.setString(19, result.getString("SECURITIES_TYPE") == null ? "" : result.getString("SECURITIES_TYPE"));
main.setString(20, result.getString("ORG_TYPE") == null ? "" : result.getString("ORG_TYPE"));
main.setString(21, result.getString("PROVINCE") == null ? "" : result.getString("PROVINCE"));
main.setString(22, result.getString("CITY") == null ? "" : result.getString("CITY"));
main.setString(23, result.getString("GRAB_LEVEL") == null ? "" : result.getString("GRAB_LEVEL"));
if (result.getString("REFRESHED_AT") != null) {
main.setDate(24, java.sql.Date.valueOf(dateFormat.format(new Date()).trim()));
}
main.setString(25, result.getString("ORG_USCC") == null ? "" : result.getString("ORG_USCC"));
main.setString(26, result.getString("COM_LOGO") == null ? "" : result.getString("COM_LOGO"));
main.setString(27, "北斗同步");
main.setDate(28, java.sql.Date.valueOf(dateFormat.format(new Date()).trim()));
//记录当前插入条数
count = count + 1;
//添加到提交集合
main.addBatch();
if (count == 1000) {
//执行提交
main.executeBatch();
//清空数据存放集合
main.clearBatch();
//提交事物
connLocal.commit();
//重置
count = 0;
}
}
//执行提交(这里是为了防止当查询出来的数据最后不足1000条时没有提交,这里在做一次提交)
main.executeBatch();
//清空数据存放集合
main.clearBatch();
//提交事物
connLocal.commit();
//分页开始增加
countStart = countStart + countEnd;
//分页结束增加
countEnd = countEnd + countEnd;
//声明查询更新后的对象(查询下一页数据)
String sql = "select * from (select rownum rn,* from COMPANY_IFIND where isvalid =1)" + " where rn<=" + countEnd + " and rn>=" + countStart;
prep = conn.prepareStatement(sql1);
//执行查询
result = prep.executeQuery();
//如果有数据了
if (result.next()) {
//重置一下记录条数,继续新增新的一页数据
count = 0;
} else {
//如果下一页没有数据了
//跳出循环
bl = false;
//关闭数据库连接
conn.close();
prep.close();
result.close();
main.close();
connLocal.close();
}
}
}
} catch (Exception e) {
log.error("查询错误:", e);
}