今天看到一篇好的关于数据库批出理插入的文章,和大家分享一下;
String [] queries = {
"insert into employee (name, city, phone) values ('A', 'X', '123')",
"insert into employee (name, city, phone) values ('B', 'Y', '234')",
"insert into employee (name, city, phone) values ('C', 'Z', '345')",
};
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();
for (String query : queries) {
statemenet.execute(query);
}
statemenet.close();
connection.close();
上面的这些代码是一般我们向数据库插入时 用的sql语句,先是定义一个数组,然后利用一个for循环 一条一条的插入数据库。他有一个缺点就是当数据量很大的时候,是很影响效率的;
下面的是改进的代码:
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();
for (String query : queries) {
statemenet.addBatch(query);
}
statemenet.executeBatch();
statemenet.close();
connection.close();
在这部分代码里 是使用了addBach方法 把sql语句加入到Statement对象里,然后一次性执行
他们,提高了效率;
还有一个就是动态的批处理插入数据:
import java.sql.Connection;
import java.sql.Statement;
//...
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();
for (Employee employee: employees) {
String query = "insert into employee (name, city) values('"
+ employee.getName() + "','" + employee.getCity + "')";
statemenet.addBatch(query);
}
statemenet.executeBatch();
statemenet.close();
connection.close();
这样动态插入是很好的,但是同时 也有一个缺点,因为他是动态的创建sql语句
,所以很容易进行sql注入,那么下面的代码 就可以这个问题:
import java.sql.Connection;
import java.sql.PreparedStatement;
//...
String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
Connection connection = new getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
for (Employee employee: employees) {
ps.setString(1, employee.getName());
ps.setString(2, employee.getCity());
ps.setString(3, employee.getPhone());
ps.addBatch();
}
ps.executeBatch();
ps.close();
connection.close();
这部分代码很好的解决了sql注入问题 ,同时也有一个新的问题,就是当我们插入的数据有十,百万条的时候,就会有可能出现OutOfMemoryError
内存不足的问题,当然这只是个硬件问题,但是有一个好的方法可以解决它:
String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
Connection connection = new getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
final int batchSize = 1000;
int count = 0;
for (Employee employee: employees) {
ps.setString(1, employee.getName());
ps.setString(2, employee.getCity());
ps.setString(3, employee.getPhone());
ps.addBatch();
if(++count % batchSize == 0) {
ps.executeBatch();
}
}
ps.executeBatch(); // insert remaining records
ps.close();
connection.close();
仅仅是加了一条判断语句判断一下 插入的数据量,就可以了。