java.sql.BatchUpdateException: 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 '('1512144017', 'quqiang01' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createBatchUpdateException(SQLError.java:1162)
at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1587)
at com.mysql.jdbc.PreparedStatement.executeBatchInternal(PreparedStatement.java:1253)
at com.mysql.jdbc.StatementImpl.executeBatch(StatementImpl.java:970)
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 '('1512144017', 'quqiang01' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2487)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2079)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2013)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5104)
at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1548)
... 5 more
最近在使用JDBC的时候,一个比较坑的细节,就是关于他里面使用PreparedStatement或者Statement 的 addBatch()/executeBatch()的具体实现问题;
不要手贱在你传入的sql语句没末尾加上分号;
具体是这样:
1 //以一个批量提交的实现工具举例 2 // List<List<Object>> lists: 所有数据的list 3 // List<Object>:单条数据"值"的list 4 5 public void batchExecutePstamt(String sql, List < List < Object >> lists) { 6 try { 7 connection.setAutoCommit(false); 8 pstmt = connection.prepareStatement(sql); 9 if (lists != null && !lists.isEmpty()) { 10 for (List < Object > cList: lists) { 11 if (cList == null || cList.isEmpty()) 12 continue; 13 14 for (int i = 0; i < cList.size(); i++) { 15 pstmt.setObject(i + 1, cList.get(i)); 16 } 17 pstmt.addBatch(); 18 } 19 log.info(pstmt.toString()); 20 pstmt.executeBatch(); 21 connection.commit(); 22 } 23 } catch (SQLException e) { 24 e.printStackTrace(); 25 } 26 }
在这里,我们传入大量的需要插入的对象的List<List<Object>>,里面的 List<Object> 就是某一条具体的记录的值;
如果你调用的时候, 在传入sql的时候, 传入了类似于 insert into `tablename` (name,age) values (?,?); 的sql语句
那么他每次addBatch的时候就会在
com.mysql.jdbc.PreparedStatement.addBatch()的创建com.mysql.jdbc.PreparedStatement.BatchParams 然后放进batchedArgs 静态列表里面
1 public void addBatch() throws SQLException { 2 synchronized (checkClosed().getConnectionMutex()) { 3 if (this.batchedArgs == null) { 4 this.batchedArgs = new ArrayList<Object>(); 5 } 6 7 for (int i = 0; i < this.parameterValues.length; i++) { 8 checkAllParametersSet(this.parameterValues[i], this.parameterStreams[i], i); 9 } 10 11 this.batchedArgs.add(new BatchParams(this.parameterValues, this.parameterStreams, this.isStream, this.streamLengths, this.isNull)); 12 } 13 }