my batis 에서 foreach 대량 insert 이상 문 제 를 해결 합 니 다.
org.springframework.jdbc.BadSqlGrammarException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO t_user_role(userid,roleid)VALUES(1,3)
;
INSERT INTO t_user_ro' at line 3
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: INSERT INTO t_user_role(userid,roleid)VALUES(?,?) ; INSERT INTO t_user_role(userid,roleid)VALUES(?,?) ; INSERT INTO t_user_role(userid,roleid)VALUES(?,?)
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO t_user_role(userid,roleid)VALUES(1,3)
;
INSERT INTO t_user_ro' at line 3
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO t_user_role(userid,roleid)VALUES(1,3)
;
INSERT INTO t_user_ro' at line 3
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
at com.sun.proxy.$Proxy13.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:240)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:51)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
at com.sun.proxy.$Proxy14.addRoles(Unknown Source)
at com.atguigu.atcrowdfunding.manager.service.impl.UserServiceImpl.addRoles(UserServiceImpl.java:139)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy17.addRoles(Unknown Source)
at com.atguigu.atcrowdfunding.manager.controller.UserController.doAddRoles(UserController.java:271)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:175)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:434)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:833)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO t_user_role(userid,roleid)VALUES(1,3)
;
INSERT INTO t_user_ro' at line 3
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:941)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3870)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3806)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2470)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2617)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2550)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.execute(NewProxyPreparedStatement.java:823)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:62)
at com.sun.proxy.$Proxy24.execute(Unknown Source)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:44)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:69)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:105)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:71)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:152)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358)
... 65 more
이상 분석mapper.xml 로 인 한 오류
<insert id="addRoles">
<foreach collection="data.ids" item="id" separator=";">
INSERT INTO t_user_role(userid,roleid)VALUES(#{userId},#{id})
</foreach>
</insert>
이상 설
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO t_user_role(userid,roleid)VALUES(1,3)
먼저 sql 문장의 문제 라 고 생각 하지만 sqlyog 테스트 를 통 해 문제 가 없 음 을 발견 하 였 습 니 다.나중에 발견 한 것 은 데이터베이스 가 여러 문장 을 한데 묶 은 조작 에 대해 지원 하지 않 는 문제 이다
해결 방법
jdbcUrl 에 allow MultiQueries=true 를 추가 하면 해결 할 수 있 습 니 다.
jdbc.url=jdbc:mysql://localhost:3306/atcrowdfunding?allowMultiQueries=true&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf8
추가:Mybatis foreach 내장 대량 삽입 맵 목록 데이터방식 1:
Teacher 와 Students 를 예 로 들 면 둘 은 한 쌍 의 다 관계 이다.**
Teacher 실체 클래스
private String tid;
private String tName;
private List<Student> studentList;
public String getTid() {
return tid;
}
public void setTid(String tid) {
this.tid = tid;
}
public String gettName() {
return tName;
}
public void settName(String tName) {
this.tName = tName;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
학생 실체 클래스
private String sid;
private String sName;
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
응용 장면:선생님 의 service 층 에 선생님 데 이 터 를 대량으로 삽입 합 니 다.
int nums=1000;
// teacher list
List<Teacher> teaList=new ArrayList<Teacher>();
// excel excel row
for(int rowi=0;rowi<nums;rowi++){
Teacher teacher=new Teacher();
teacher.settName("xxx");
List<Student> stuList=new ArrayList<Student>();
Student student=new Student();
// Students
for(xxx){
stuList.add(student);
}
// student teacher
teacher.setStudentList(stuList);
// teacher list
teaList.add(teacher);
}
//
teacherMapper.batchInsertTeacher(teaList);
// teacher id
// list( ) map
Map<String,List<Student>> stuMap=new HashMap<>();
//
for(Teacher tea:teaList){
// ( )
if(tea.getStudentList()!=null&&tea.getStudentList().size()>0){
stuMap.put(tea.getTid(),tea.getStudentList());
}
}
// service
studentService.batchInsertStudent(stuMap);
학생 Mapper 인터페이스 파일
int batchInsertStudent(@Param("stuMap") Map<String,List<Student>> stuMap);
student mapper.xml 파일(쓰기 1:)
<insert id="batchInsertStudent" parameterType="java.util.Map">
INSERT INTO bs_student (sid,sName,tid)
values
<foreach collection="stuMap.keys" index="key" item="itemKey" separator=",">
<foreach collection="stuMap[itemKey]" index="index_list" item="list" separator="," >
( (select REPLACE(UUID(),'-','') AS sid) ,#{list.sName},#{itemKey} )
</foreach>
</foreach>
</insert>
student mapper.xml 파일(쓰기 2:)
<insert id="batchInsertStudent" >
INSERT INTO bs_student (sid,sName,tid)
<foreach collection="stuMap.keys" index="index" item="itemKey" separator="UNION ALL">
<foreach collection="stuMap[itemKey]" index="index_list" item="list" separator="UNION ALL">
(
SELECT
(select REPLACE(UUID(),'-','') AS sid)
,#{list.sName}
,#{itemKey}
FROM DUAL
)
</foreach>
</foreach>
</insert>
stuMap:인터페이스 에@Param("stuMap")을 사용 하여 변 수 를 표시 합 니 다.stuMap.keys 를 사용 하면 모든 key 를 가 져 와 옮 겨 다 닐 수 있 습 니 다.
내부 순환 에서 stuMap[itemKey]와 유사 한 stuMap.get("key")을 사용 하여 현재 key 에 대응 하 는 value 값 을 가 져 옵 니 다.value 는 list 이기 때문에 옮 겨 다 녀 야 합 니 다.
결과 저장 에 성 공 했 습 니 다.강력 한 마 이 바 티 스 를 다시 한 번 경 배 합 니 다.
이로써 student 데 이 터 를 성공 적 으로 삽입 하 였 습 니 다.
방식 2(추천):
사용자 정의 클래스
class EnclosingType{
private String uuid;
private List<ElementType> elements;
}
class ElementType{
String a;
String b;
(...)
}
Mapper.xml(방법 1)
<mapper namespace="my.example.ElementType">
<insert id="insertElements" parameterType="EnclosingType">
INSERT INTO table1(enclosingTypeId,column_a,column_b)
VALUES
<foreach collection="elements" index="index" item="list" separator=",">
(
#{uuid,jdbcType=VARCHAR}
,#{list.a,jdbcType=VARCHAR}
,#{list.b,jdbcType=VARCHAR}
)
</foreach>
</insert>
</mapper>
Mapper.xml(방법 2)
<mapper namespace="my.example.ElementType">
<insert id="insertElements" parameterType="EnclosingType">
INSERT INTO table1(enclosingTypeId,column_a,column_b)
<foreach collection="elements" index="index" item="list" separator="union all">
(
select #{uuid,jdbcType=VARCHAR}
,#{list.a,jdbcType=VARCHAR}
,#{list.b,jdbcType=VARCHAR}
from dual
)
</foreach>
</insert>
</mapper>
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.만약 잘못 이 있 거나 완전히 고려 하지 않 은 부분 이 있다 면 아낌없이 가르침 을 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MySQL/마이바티스 | 동적 쿼리 사용A라는 서비스에 해당하는 테이블을 조인하고 조회하는 데 사용됩니다. 나중에 공통화를 위해 B 및 C 서비스도 추가됩니다. A, B, C 서비스는 모두 단일 쿼리에서 작동할 수 있도록 공통화되어야 합니다. 테이블에 각...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.