一.需求
应业务改变的需要,原来的老系统中需要写入大量数据到数据库。
二.异常
正常插入数据库,则报以下异常。
com.microsoft.sqlserver.jdbc.SQLServerException: 传入的请求具有过多的参数。该服务器支持最多 2100 个参数。请减少参数的数目,然后重新发送该请求。
百度原因:
SqlServer
对语句的条数和参数的数量都有限制,分别是 1000 和 2100。Mysql
对语句的长度有限制,默认是 4M。Mybatis
对动态语句没有数量上的限制
三.解决办法
分批次插入或者更新
四.具体实现
1.如果sqlsessionFactory已经注入,则使用注解直接过去该对象
/**
* @Author:user
* @Date 创建日期 2018/8/2
* @Modified By:
* @Description:
*/
@Service
public class TempServiceImpl implements ITempService {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Override
@Transactional
public boolean save(List autoBatcyList) {
boolean flag = false;
try( SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);) {
//由于数据库对于插入字段的限制,在这里对批量插入的数据进行分批处理
int batchCount =120;//每批commit的个数
int batchLastIndex = batchCount - 1;// 每批最后一个的下标
for (int index = 0; index <= autoBatcyLIst.size() - 1;) {
if (batchLastIndex > autoBatcyList.size() - 1) {
batchLastIndex = autoBatcyList.size() - 1;
sqlSession.insert("com.demo.dao.ITempDao.save", autoBatcyList.subList(index, batchLastIndex + 1));
sqlSession.commit();
break;// 数据插入完毕,退出循环
} else {
sqlSession.insert("com.demo.dao.ITempDao.save", autoBatcyList.subList(index, batchLastIndex + 1));
sqlSession.commit();
index = batchLastIndex + 1;// 设置下一批下标
batchLastIndex = index + (batchCount - 1);
}
}
sqlSession.commit();
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
}
2.sql实现
<insert id="save" parameterType="java.util.List">
<foreach collection="list" item="item">
insert into
demo(name,age,address,school,addtime)
values (#{item.name},#{item.age},#{item.address},#{item.school},GETDATE())
</foreach>
</insert>
至此,解决问题。