java数据库批量插⼊数据
jdbc知识介绍
|-- Statement
-- PreparedStatement  ⼦接⼝,建议使⽤,会对sql语句先进⾏编译再给数据库
PreparedStatement对象不仅包含了SQL语句,⽽且⼤多数情况下这个语句已经被预编译过,因⽽当其执⾏时,只需DBMS运⾏SQL语句,⽽不必先编译。
当你需要执⾏Statement对象多次的时候,PreparedStatement对象将会⼤⼤降低运⾏时间,当然也加快了访问数据库的速度。
批处理相关⽅法
void addBatch(String sql)  添加批处理
void clearBatch()      清空批处理
int[] executeBatch()    执⾏批处理
事务提交
con.setAutoCommit(false);    默认⾃动提交,在这⾥需要设置为false,⼿动提交
conmit();
3.常见问题
批量处理⽆法⽣效
1、rewriteBatchedStatements=true
代码演⽰
1普通插⼊⽅式
10万条数据,耗时15秒
private String url = "jdbc:mysql://localhost:3306/test01";
private String user = "root";
private String password = "123456";
@Test
public void Test(){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rt = null;
try {
Class.forName("sql.jdbc.Driver");
conn = Connection(url, user, password);
String sql = "INSERT INTO myTable values(?,?)";
pstm = conn.prepareStatement(sql);
Long startTime = System.currentTimeMillis();
for (int i = 1; i <= 100000; i++) {
pstm.setInt(1, i);
pstm.setInt(2, i);
}
Long endTime = System.currentTimeMillis();
System.out.println("⽤时:" + (endTime - startTime));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
if(pstm!=null){
try {
pstm.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
2使⽤batch
注意更改url = “jdbc:mysql://localhost:3306/test01?rewriteBatchedStatements=true”; pstm.addBatch();代替uteUpdate();
最后批量操作uteBatch();
10万条数据,耗时4秒
private String url = "jdbc:mysql://localhost:3306/test01?rewriteBatchedStatements=true";    private String user = "root";批量更新sql语句
private String password = "123456";
@Test
public void Test() {
Connection conn = null;
PreparedStatement pstm = null;
ResultSet rt = null;
try {
Class.forName("sql.jdbc.Driver");
conn = Connection(url, user, password);
String sql = "INSERT INTO myTable values(?,?)";
pstm = conn.prepareStatement(sql);
Long startTime = System.currentTimeMillis();
conn.setAutoCommit(false);
for (int i = 1; i <= 100000; i++) {
pstm.setInt(1, i);
pstm.setInt(2, i);
//1w提交⼀次
pstat.addBatch();
if (i % 10000 == 0) {
pstat.clearBatch();
}
}
//提交余下部分
pstat.clearBatch();  //清空批处理
conmit();
Long endTime = System.currentTimeMillis();
System.out.println("⽤时:" + (endTime - startTime));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (pstm != null) {
try {
pstm.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
Mybatis⽅式
<insert id="insertBatch" >
insert into student ( <include refid="Base_Column_List" /> )
values
<foreach collection="list" item="item" index="index" separator=",">
(null,#{item.name},#{item.sex},#{item.address},#{lephone},#{item.tId})
</foreach>
</insert>
参数解释:
collection:指定要遍历的集合;
表⽰传⼊过来的参数的数据类型。该参数为必选。要做 foreach 的对象,作为⼊参时,List 对象默认⽤ list 代替作为键,数组对象
有 array 代替作为键,Map 对象没有默认的键
item:将当前遍历出的元素赋值给指定的变量,然后⽤#{变量名},就能取出变量的值,也就是当前遍历出的元素
separator:每个元素之间的分隔符, select * from Emp where id in(1,2,3)相当于1,2,3之间的","
Index:索引,遍历list的时候index就是索引,遍历map的时候index表⽰的就是map的key,item就是map的值.
特别注意:mysql默认接受sql的⼤⼩是1048576(1M),即第三种⽅式若数据量超过1M会报如下异常:(可通过调整MySQL安装⽬录下的my.ini⽂件中[mysqld]段的"max_allowed_packet = 1M")
mybatis的 ExecutorType.BATCH
Mybatis内置的ExecutorType有3种,默认的是simple,该模式下它为每个语句的执⾏创建⼀个新的预处理语句,单条提交sql;⽽batch 模式重复使⽤已经预处理的语句,并且批量执⾏所有更新语句,显然batch性能将更优; 但batch模式也有⾃⼰的问题,⽐如在Insert操作时,在事务没有提交之前,是没有办法获取到⾃增的id,这在某型情形下是不符合业务要求的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。