The first:
Because each data transmission Mysql sql statement can not be longer than 1M, therefore, each transmission sent in fixed-length insert statements:
Sql statement in the provider, the fixed length set of charged List, and then return to the service layer, MAPP call, send sql statement
// provider class public class sql { private List <String> sqlList = new ArrayList<>(); private void makeUpSql(StringBuilder sql, StringBuilder paramSql2) { sqlList.add(sql.append(paramSql2.substring(0, paramSql2.length()-1)).toString()); } @SuppressWarnings("unchecked") public List<String> batchInsert(Map<String, Object> map) throws Exception { List<IBean> beans = (List<IBean>) map.get("list"); int length = Numbers.parseInt(map.get("length")); Class<?> bclz = beans.get(0).getClass(); StringBuilder sql = batchInsertBeforeSql(beans); int sizeBefore = sql.toString().getBytes().length; StringBuilder paramSql2 = new StringBuilder(); for (IBean bean : beans) { int sizeSql1 = paramSql2.toString().getBytes().length+sizeBefore; StringBuilder paramSql2c = new StringBuilder(paramSql2.toString()); paramSql2.append("("); for(Field f : bclz.getDeclaredFields()) { f.setAccessible(true); if (! Modifier.isStatic (f.getModifiers ())) {// non-static resources String fname = f.getName(); if("id".equals(fname) ) { continue; } String value = Strings.of(f.get(bean)).replaceAll("\"", "\\\\\""); value = value.replaceAll("\'", "\\\\\'"); paramSql2.append("\"").append(value).append("\", "); } } paramSql2 = new StringBuilder(paramSql2.substring(0, paramSql2.length()-2)); paramSql2.append("),"); if(sizeSql1<length && paramSql2.toString().getBytes().length+sizeBefore>=length) { makeUpSql(sql,paramSql2c); Map<String, Object> map1 = new HashMap<>(); List<IBean> nextList = beans.subList(beans.indexOf(bean), beans.size()); map1.put("list", nextList); map1.put("length", length); return batchInsert(map1); } } sqlList.add(sql.append(paramSql2.substring(0, paramSql2.length()-1)).toString()); return sqlList; } public StringBuilder batchInsertBeforeSql(List<IBean> beans) { StringBuilder sql = new StringBuilder("insert into "); Class<?> bclz = beans.get(0).getClass(); sql.append(bclz.getSimpleName().toLowerCase()).append(" ("); StringBuilder paramSql = new StringBuilder(); for(Field f : bclz.getDeclaredFields()) { f.setAccessible(true); if (! Modifier.isStatic (f.getModifiers ())) {// non-static resources String fname = f.getName(); if("id".equals(fname) ) { continue; } paramSql.append(",").append(fname); } } return sql.append(paramSql.substring(1)).append(") values "); } // service layer public void sendSql(List<String> listSql) { for (String sql : listSql) { Mapper.batchInsert3(sql); } // mapper layer @Insert("${sql}") int batchInsert3(@Param("sql") String sql);
The second:
Create a session, each of the single insert statement calling mapper, use the session unification commit
// If you specify multiple data sources, you need to add annotations @Qualifier, SqlSessionTemplate specify which database to use @Qualifier("kwSqlSessionTemplate") private SqlSessionTemplate sqlSessionTemplate; public void batchInsert(List<Issue> beanList) { SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false); IssueMapper mapper = session.getMapper(IssueMapper.class); try { for (int i = 0;i<beanList.size();i++) { mapper.insert(beanList.get(i)); if(i%1000==999 || i==beanList.size()-1) { session.commit(); session.clearCache(); } } }catch(Exception e) { e.printStackTrace (); session.rollback(); }finally { session.close(); } }