第一种 XML里面定义好SQL
void updateBatch(List userPermission);
SELECT LAST_INSERT_ID()
insert into user_permission ( )
values
#{item.id,jdbcType=BIGINT},#{item.bid,jdbcType=BIGINT}, #{item.fid,jdbcType=BIGINT},#{item.buttonName,jdbcType=VARCHAR},#{item.buttonState,jdbcType=BIGINT},#{item.effective,jdbcType=BIGINT},#{item.createAt,jdbcType=TIMESTAMP}
id,bid,fid,button_Name,button_state,effective,create_at
selectKey是用来自增长主键Id,如果使用的mybatis3.3.*以下的版本是有自增长的bug,mybatis3.3.*以上的版本是修复了该bug.
第二种 在Mapper里自定义Provider
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.InsertProvider;
public interface StudentMapper {
@InsertProvider(type = Provider.class, method = "batchInsert")
int batchInsert(List students);
class Provider {
/* 批量插入 */
public String batchInsert(Map map) {
List students = (List) map.get("list");
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO student (name,sex,addr) VALUES ");
MessageFormat mf = new MessageFormat(
"(#'{'list[{0}].name}, #'{'list[{0}].sex}, #'{'list[{0}].addr})"
);
for (int i = 0; i < students.size(); i++) {
sb.append(mf.format(new Object[] {i}));
if (i < students.size() - 1)
sb.append(",");
}
return sb.toString();
}
}
问题及解决
SqlServer 对语句的条数和参数的数量都有限制,分别是 1000 和 2100。
Mysql 对语句的长度有限制,默认是 4M。 这个错误是 Mysql 的JDBC包抛出的。
Mybatis 对动态语句没有数量上的限制。
SqlServer解决:分批次插入
@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;
}
}
insert into
demo(name,age,address,school,addtime)
values (#{item.name},#{item.age},#{item.address},#{item.school},GETDATE())
参考:https://blog.csdn.net/qq_24607837/article/details/81381934
Mysql解决:
## 查询当前大小
mysql> select @@max_allowed_packet;
+----------------------+
| @@max_allowed_packet |
+----------------------+
| 4194304 |
+----------------------+
1 row in set (0.00 sec)
## 修改为256M
mysql> SET GLOBAL max_allowed_packet=268435456;
Query OK, 0 rows affected (0.00 sec)
## 退出客户端重新登录
mysql> select @@max_allowed_packet;
+----------------------+
| @@max_allowed_packet |
+----------------------+
| 268435456 |
+----------------------+
1 row in set (0.00 sec)