创建表
CREATE TABLE PERSON
(
PID NUMBER(10),
NAME VARCHAR2(50),
GENDER NUMBER(12) DEFAULT 1
);
1、Java 批处理
1.1、批量 Insert
// oracle 批处理 Demo
try {
long start = System.currentTimeMillis();
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@//192.168.0.106:1521/XE",
"sunxikai",
"123456");
// 可以直接在sql中拼上sequence 这里用name + id 拼接name
String sql = "INSERT INTO PERSON (PID, NAME, GENDER) VALUES (CODE_BASE_ID_SEQ.nextval, concat('name', CODE_BASE_ID_SEQ.currval), ?)";
PreparedStatement ptmt = conn.prepareStatement(sql);
for (int i = 0; i < 5000; i++) {
ptmt.setInt(1, i); // 参数从 1 开始
ptmt.addBatch();
}
ptmt.executeBatch();// 执行批处理
long end = System.currentTimeMillis();
System.out.println(end - start); // 时间 1457
ptmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
1.2、批量 update
try {
long start = System.currentTimeMillis();
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@//192.168.0.106:1521/XE",
"sunxikai",
"123456");
String sql = "UPDATE PERSON p1 SET (p1.NAME, p1.GENDER) = (SELECT concat('hhaha', p.PID),p.GENDER + 40000 FROM PERSON p WHERE p.PID = ?) WHERE p1.PID = ?";
PreparedStatement ptmt = conn.prepareStatement(sql);
for (int i = 10000; i < 15000; i++) {
ptmt.setInt(1, i);
ptmt.setInt(2, i);
ptmt.addBatch();
}
ptmt.executeBatch();
long end = System.currentTimeMillis();
System.out.println(end - start); // 13872 时间是比较长的
ptmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
动态拼接sql批量处理 有长度限制
1.简单的批处理性能很好(拼接的sql长度不能太长2000以内的集合,并且没有超长的字段应该没有问题)
2.对于数据表字段中存在大数据如:CLOB类型,就不能使用这种批量方法。
Oracle数据库 id是序列
<insert id="methodId" parameterType="java.util.List">
insert into table(id,age,name)
select table_id_seq.nextval,a.* from (
<foreach item="item" collection="list" index="index" separator="UNION ALL">
SELECT
#{item.age,jdbcType=NUMERIC},
#{item.name,jdbcType=VARCHAR}
from dual
</foreach>
) a
</insert>
mysql id自增
<insert id="methodId" parameterType="java.util.List">
insert into table(age,name) values
<foreach item="item" collection="list" index="index" separator=",">
(#{item.age}, #{item.name})
</foreach>
</insert>
mybatis SQLSession 批处理
MyBatis 获得sqlSession 可以进行批量更新:
采用dao层循环,得到sqlsession 统一commit,这种方式几乎可以应付你所有的情况
@Autowired
private SqlSessionTemplate sqlSession;
public void saveBatch(List<TBsImpNews> modelList) {
SqlSession session = sqlSession.getSqlSessionFactory()
.openSession(ExecutorType.BATCH, false);
try{
//批量生成主键
for(TBsImpNews tBsImpNews : modelList){
//生成主键
String impnewsId =String.valueOf(Long.valueOf(getSequenceNextId(SEQ_T_BS_IMP_NEWS)));
tBsImpNews.setImpnewsId(impnewsId);
sqlSession.insert("com.rocktrue.fastdev.wvsp.impnews.TBsImpNewsMapper.insertTBsImpNews", tBsImpNews);
for(String url:tBsImpNews.getImgList()){
//批量生成新闻图片主键
String imniId =String.valueOf(Long.valueOf(getSequenceNextId(SEQ_T_BS_IMP_NEWS_IMG)));
TBsImpNewsImg tBsImpNewsImg=new TBsImpNewsImg();
tBsImpNewsImg.setImniId(imniId);
tBsImpNewsImg.setImpnewsId(impnewsId);
tBsImpNewsImg.setImniSrc(url);
sqlSession.insert("com.rocktrue.fastdev.wvsp.impnews.TBsImpNewsImgMapper.insertTBsImpNewsImg", tBsImpNewsImg);
}
}
session.commit();
//清理缓存,防止溢出
session.clearCache();
}catch(Exception e){
e.printStackTrace();
session.rollback();
}finally {
session.close();
}
}