java大数据量执行几千条修改/删除的sql设置条数批量优化执行

记录一种大数据修改或者删除的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;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值