想要向mysql中插入大量数据(10w+)时,使用单纯的insert会很慢。我们需要借助JDBC的批处理。
1. jdbc连接url增加rewriteBatchedStatements属性
需要在数据库连接url中增加一个属性rewriteBatchedStatements=true
,这个属性默认是false,开启后JDBC会执行executeBatch();(这里需要mysql-connector-java
的版本在5.1.13以上才有用)
2. sql语句
我们需要使用insert into table_name ('colum1','colum2') values ('value1','value2')
语句,这里注意后面不要加;
3. 批量操作
我们这里使用TiDB数据库,对于每次提交的数据大小有限制,所以判断每1w次提交一次,代码如下:
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(SysConstant.TiDB_URL, SysConstant.TiDB_USERNAME, SysConstant.TiDB_PASSWORD);
String sql = "replace into test (EntityID,EntityName) values (?,?)";
PreparedStatement st = conn.prepareStatement(sql);
//如果需要分批操作,每次通过commit提交事务,则需要设置自动提交为false
conn.setAutoCommit(false);
try {
for(int i = 0; i < earlyWarnings.size(); i++){
st.setString(1, earlyWarnings.get(i).getEntity());
st.setString(2, earlyWarnings.get(i).getEntityName());
st.addBatch();
//每超过1w条调用一次保存(tidb每次限制提交事务的大小)
if (i % 10000 == 0) {
st.executeBatch();
conn.commit();
}
}
//保存剩下的数据
st.executeBatch();
conn.commit();
}catch (Exception e){
logger.info("Exception when storeEarlyWarningStatusRT: ", e);
}finally {
st.close();
conn.close();
}
如果没有限制可以直接使用以下代码:
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(SysConstant.TiDB_URL, SysConstant.TiDB_USERNAME, SysConstant.TiDB_PASSWORD);
String sql = "replace into test (EntityID,EntityName) values (?,?)";
PreparedStatement st = conn.prepareStatement(sql);
try {
for(int i = 0; i < earlyWarnings.size(); i++){
st.setString(1, earlyWarnings.get(i).getEntity());
st.setString(2, earlyWarnings.get(i).getEntityName());
st.addBatch();
}
st.executeBatch();
}catch (Exception e){
logger.info("Exception when storeEarlyWarningStatusRT: ", e);
}finally {
st.close();
conn.close();
}