记录一种大数据修改或者删除的sql批量分大小执行优化的方法
首先需要注入entitymanager对象
@PersistenceContext(type = PersistenceContextType.EXTENDED)
EntityManager entityManager;
实际代码如下
//设置存储插入对象
List<String> userList= new ArrayList<>();
//优化代码存储变量
StringBuffer sqlAppend = new StringBuffer();
//存储所有sql语句集合
List<String> arrList = new ArrayList<>();
userList.add("张三");
userList.add("李四");
userList.add("王五");
···
//循环整理插入sql
for (String userName : userList) {
HashMap map = new HashMap();
//UUID
map.put("ID",UUID.randomUUID().toString())
map.put("NAME",userName )
//map为所需转换sql语句的对象,USERINFO为表名,方法在后面有贴代码
String sqlInsert = insertFromMapOfItem(map, "USERINFO");
if (!"".equals(sqlInsert)) {
arrList.add(sqlInsert);
}
}
//保存所有sql语句条数
long sqlCount = 0;
//指定每次运行1000条sql
int sqlRunCount = 1000;
//保存所有insert语句
Map<String, String> sqlMap = new HashMap<String, String>();
//遍历存储sql语句的集合
for (String sql : arrList) {
sqlAppend.append(sql);
sqlCount++;
if (sqlCount == sqlRunCount) {
//当集合大小等于所设置的执行大小时存入最终执行sqlMap并将对比值设为0和插入语句清空以重新开始
sqlMap.put(String.valueOf(sqlMap.size() + 1), sqlAppend.toString());
sqlAppend.setLength(0);
sqlCount = 0;
}
}
//当最后整理后的集合大小不足设置的执行大小时存入最终执行sqlMap
if (sqlAppend.length() != 0) {
sqlMap.put(String.valueOf(sqlMap.size() + 1), sqlAppend.toString());
sqlAppend.setLength(0);
sqlCount = 0;
}
/*上述 *** 作后所有批量sql语句就按照设置大小依次存入了sqlMap
不然如果直接执行大数据量的批量语句会导致超长报错
*/
//遍历最终容器依次执行大数据sql
for (String key : sqlMap.keySet()) {
//使用entitymanager执行sql
entityManager.createNativeQuery(sqlMap.get(key)).executeUpdate();
}
将map转换为插入sql的方法如下。有条件的话其实可以使用JPA的实体批量保存
或者批量删除方法,批量保存用saveAll、删除用deleteAll()或者
deleteAllInBatch(),
区别是deleteAll()是删除全部,先找出所有再一条一条的删除,
最后再提交事务。deleteAllInBatch()是一次性删除全部,当然用后者效率更高
//将map类型转换为插入sql的语句
public String insertFromMapOfItem(HashMap<String, Object> map, String tablename) {
//构建插入列名
ArrayList<Object> arrKey = new ArrayList<>();
//构建插入值
ArrayList<Object> arrValue = new ArrayList<>();
for (String key : map.keySet()) {
arrKey.add(key);
}
for (String keys : map.keySet()) {
arrValue.add(map.get(keys));
}
//插入列sql
StringBuffer strKey = new StringBuffer();
//插入列sql
StringBuffer strVal = new StringBuffer();
//拼接插入列sql
for (int j = 0; j < arrKey.size(); j++) {
strKey.append(arrKey.get(j));
if (j != arrKey.size() - 1) {//前面的元素后面全拼上",",最后一个元素后不拼
strKey.append(",");
}
}
//拼接插入值sql
for (int j = 0; j < arrValue.size(); j++) {
if (null != arrValue.get(j) && !"".equals(arrValue.get(j))) {
strVal.append("'" + arrValue.get(j) + "'");//拼接单引号
} else if ("".equals(arrValue.get(j))) {
strVal.append("" + null + "");
} else {
strVal.append(arrValue.get(j));
}
if (j != arrValue.size() - 1) {//前面的元素后面全拼上",",最后一个元素后不拼
strVal.append(",");
}
}
String stringEntryKey = strKey.toString();
String stringEntryVal = strVal.toString();
//保存
String sqlEntry = "INSERT INTO " + tablename + " (" + stringEntryKey + ") VALUES (" + stringEntryVal + ");";
return sqlEntry;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)