For anyone using java with JDBC, it is possible. I am getting ids back with batch-insert doing it like this:
PreparedStatement insertBatch = null; Connection connection = ....; for (Event event : events) { if (insertBatch == null){ insertBatch = connection.prepareStatement("insert into `event` (game, `type`, actor, target, arg1, arg2, arg3, created) " + "values (?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS); } insertBatch.setObject(1, event.game); insertBatch.setString(2, event.type); insertBatch.setObject(3, event.actor); insertBatch.setObject(4, event.target); insertBatch.setString(5, event.arg1); insertBatch.setObject(6, event.arg2); insertBatch.setObject(7, event.arg3); insertBatch.setTimestamp(8, new Timestamp(event.created.getTime())); insertBatch.addBatch(); } } if (insertBatch != null){ insertBatch.executeBatch(); ResultSet generatedKeys = insertBatch.getGeneratedKeys(); for (Event event : events) { if ( generatedKeys == null || ! generatedKeys.next()){ logger.warn("Unable to retrieve all generated keys"); } event.id = generatedKeys.getLong(1); } logger.debug("events inserted"); }
Source: "Using MySQL I can do it with JDBC this way:" - Plap - https://groups.google.com/g/jdbi/c/ZDqnfhK758g?pli=1
I have to actually add this to my JDBC url: rewriteBatchedStatements=true. Or else the actual inserts show up in the mysql "general query log" as separate rows. With 7000 rows inserted, I got 2m11s for regular inserts, 46s without rewrite.. on and 1.1s with rewrite.. on. Also, it does not make other people's inserts block (I tested that). When I inserted 200k rows, it grouped them into about 36k per line ie insert into abc(..) values(..),(..),(..)....
I am actually using JDBCTemplate so the way to access the PreparedStatement is:
ArrayList<Long> generatedIds = (ArrayList<Long>) jdbcTemplate.execute( new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { return connection.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS); } }, new PreparedStatementCallback<Object>() { @Override public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException { // see above answer for setting the row data ... ps.executeBatch(); ResultSet resultSet = ps.getGeneratedKeys(); ArrayList<Long> ids = new ArrayList<>(); while (resultSet.next()) { ids.add(resultSet.getLong(1)); } return ids; } } );
OUTPUTclause. I believe you can do this with a trigger in MySQL