Java Oracle 批量插入实现指南
在Java中向Oracle数据库批量插入数据有几种高效的方法,以下是几种常用的实现方式:

使用PreparedStatement的addBatch()方法
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class BatchInsertExample {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@localhost:1521:ORCL";
String user = "username";
String password = "password";
String sql = "INSERT INTO employees (id, name, department, salary) VALUES (?, ?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置自动提交为false,以便控制批量提交
conn.setAutoCommit(false);
// 添加批量数据
for (int i = 1; i <= 1000; i++) {
pstmt.setInt(1, i);
pstmt.setString(2, "Employee " + i);
pstmt.setString(3, "Department " + (i % 5 + 1));
pstmt.setDouble(4, 50000 + (i * 100));
pstmt.addBatch();
// 每100条提交一次
if (i % 100 == 0) {
pstmt.executeBatch();
conn.commit();
}
}
// 执行剩余的批次
pstmt.executeBatch();
conn.commit();
System.out.println("批量插入完成");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
使用Oracle的批量插入优化
Oracle数据库对批量插入有特殊优化,可以使用以下方法:
使用Oracle的批量绑定
// 在创建PreparedStatement时设置批量大小
pstmt = conn.prepareStatement(sql, new int[] {1, 2, 3, 4});
// 或者使用Oracle特定的批量操作
OraclePreparedStatement ops = (OraclePreparedStatement) pstmt;
ops.setExecuteBatch(100); // 设置批量大小
使用Oracle的批量插入语法
String sql = "INSERT ALL INTO employees VALUES (1, 'John', 'IT', 50000) " +
"INTO employees VALUES (2, 'Jane', 'HR', 55000) " +
"SELECT * FROM dual";
使用JPA/Hibernate的批量插入
如果使用JPA/Hibernate,可以这样实现批量插入:
// 在persistence.xml中设置
<property name="hibernate.jdbc.batch_size" value="50" />
<property name="hibernate.order_inserts" value="true" />
<property name="hibernate.order_updates" value="true" />
// 代码中
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
for (int i = 0; i < 1000; i++) {
Employee emp = new Employee();
emp.setId(i);
emp.setName("Employee " + i);
em.persist(emp);
if (i % 50 == 0) {
em.flush();
em.clear();
}
}
em.getTransaction().commit();
em.close();
使用Spring JDBC的批量操作
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
public class SpringBatchInsert {
private JdbcTemplate jdbcTemplate;
public void batchInsert(List<Employee> employees) {
String sql = "INSERT INTO employees (id, name, department, salary) VALUES (?, ?, ?, ?)";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Employee emp = employees.get(i);
ps.setInt(1, emp.getId());
ps.setString(2, emp.getName());
ps.setString(3, emp.getDepartment());
ps.setDouble(4, emp.getSalary());
}
@Override
public int getBatchSize() {
return employees.size();
}
});
}
}
性能优化建议
- 调整批量大小:通常100-1000之间效果较好,需要测试确定最佳值
- 关闭自动提交:手动控制事务提交
- 使用批量绑定:Oracle特有的优化方式
- 减少网络往返:尽量在一次网络传输中发送更多数据
- 考虑使用Oracle的批量插入语法:对于极大量数据更高效
注意事项
- 确保数据库连接池配置合理
- 处理好异常情况,避免部分数据插入导致数据不一致
- 对于超大批量数据,考虑分批次处理
- 监控数据库性能,避免锁表等问题
方法可以根据具体项目需求和性能要求选择合适的实现方式。

