JPA批量入库(在高并发的情况下需要进行批量往数据库插入对象,jpa貌似没有提供处理批量插入的接口)

 

处理办法一 
利用jpa提供的saveALL(Iterator it)方法

但是把日志打印出来还是hibernate一条一条插入的,不过效率已经提高好几个数量级了,自己分析原因可能是减少了与数据库建立链接的开销,减少了事务建立的开销。

处理办法二 
用EntityManager做批量处理

@PersistenceContext
protected EntityManager entityManager;

@Transactional(propagation= Propagation.REQUIRED)
public void batchInsert(List list) {
try {
int size = list.size();
for (int i = 0; i < size; i++) {
entityManager.persist(list.get(i));
if (i % 1000 == 0 || i == (size - 1)) {
//一次一千条插入
entityManager.flush();
entityManager.clear();
}
}
log.info("入库成功,共 {}条数据", list.size());
} catch (Exception e) {
log.error("批量插入失败");
e.printStackTrace();
}
}

public void saveBatch(List<RealtimeBilateralOptimalQuote> list) {
int batchSize = 1000;
Long beginTime = System.currentTimeMillis();
EntityManagerFactory emf = entityManager.getEntityManagerFactory();
EntityManager entityManager = emf.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
try {
entityTransaction.begin();
for (int i = 0; i < list.size(); i++) {
if (i > 0 && i % batchSize == 0) {
entityTransaction.commit();
entityTransaction.begin();
entityManager.flush();
entityManager.clear();
}
entityManager.persist(list.get(i));
}
entityTransaction.commit();
} catch (RuntimeException e) {
if (entityTransaction.isActive()) {
entityTransaction.rollback();
}
throw e;
} finally {
entityManager.close();
}
Long endTime = System.currentTimeMillis();
System.out.println("pst+batch:" + (endTime - beginTime) / 1000 + "秒");
}
处理办法三 
用自己拼接sql批量插入

INSERT INTO table_name
(列1, 列2,...)
VALUES
(值1, 值2,....),
(值1, 值2,....),

 

处理办法四
NamedParameterJdbcTemplate 
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

public int batchInsertBeans(List<RealtimeBilateralOptimalQuote> list){
StringBuffer sqlKey = new StringBuffer();
StringBuffer sqlValue = new StringBuffer();
sqlKey.append("insert into t_bilateral_optimal_quote ( ");
sqlValue.append(" values ( ");
sqlKey.append("c_id, c_bidpx, c_bidsize, c_ofrpx, c_ofrsize, c_scquotetime, c_securityid, c_securitytype, c_symbol, c_bidbargainflag, c_bidcomment, c_bidexerciseflag, c_bidid, c_bidnetprice, c_bidpricetype, c_bidrelationflag, c_bidyield, c_bondcode, c_bidsize_detail, c_ofrsize_detail, c_listedmarket, c_ofrbargainflag, c_ofrcomment, c_ofrexerciseflag, c_ofrid, c_ofrnetprice, c_ofrpricetype, c_ofrrelationflag, c_ofryield)");
sqlValue.append("HIBERNATE_SEQUENCE.nextval, :BidPx, :BidSize, :OfrPx, :OfrSize, :SCQuoteTime, :SecurityID, :SecurityType, :Symbol, :bidBargainFlag, :bidComment, :bidExerciseFlag, :bidID, :bidNetPrice, :bidPriceType, :bidRelationFlag, :bidYield, :bondCode, :detailBidSize, :detailOfrSize, :listedMarket, :ofrBargainFlag, :ofrComment, :ofrExerciseFlag, :ofrID, :ofrNetPrice, :ofrPriceType, :ofrRelationFlag, :ofrYield )");
sqlKey.append(sqlValue);
return batchUpdateBeans(sqlKey.toString(), list);
}

public int batchUpdateBeans(String insertSql, List beans) {
int[] results = null;
try {
SqlParameterSource[] params = SqlParameterSourceUtils
.createBatch(beans.toArray());
results = this.namedParameterJdbcTemplate.batchUpdate(insertSql,
params);
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
return results.length;
}

 

posted on 2019-10-29 16:18  花非花-雾非雾  阅读(1948)  评论(0)    收藏  举报