日期:2014-05-16  浏览次数:20743 次

关于spring jdbcTemplate取得LAST_INSERT_ID
spring的jdbctemplate提供的方案:
KeyHolder keyHolder = new GeneratedKeyHolder();
int updatecount = jdbcTemplate.update(new PreparedStatementCreator() {
	@Override
	public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
		PreparedStatement ps = (PreparedStatement) connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
		return ps;
	}
}, keyHolder);
long id = keyHolder.getKey().longValue();


jdbctemplate中执行的相关源码
public int update(PreparedStatementCreator psc, final KeyHolder generatedKeyHolder)
        throws DataAccessException
    {
        Assert.notNull(generatedKeyHolder, "KeyHolder must not be null");
        logger.debug("Executing SQL update and returning generated keys");
        Integer result = (Integer)execute(psc, new PreparedStatementCallback() {

            public Object doInPreparedStatement(PreparedStatement ps)
                throws SQLException
            {
//第一步:通过PreparedStatement对象先执行相关sql
                int rows = ps.executeUpdate();
                List generatedKeys = generatedKeyHolder.getKeyList();
                generatedKeys.clear();
//第二步:通过同一个PreparedStatement取得产生的auto-generated keys
                ResultSet keys = ps.getGeneratedKeys();
                if(keys != null)
                    try
                    {
                        RowMapper rowMapper = getColumnMapRowMapper();
                        RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1);
//解析取得的ResultSet,放入到holder对象的,供我们的应用程序使用
                        generatedKeys.addAll((List)rse.extractData(keys));
                    }
                    finally
                    {
                        JdbcUtils.closeResultSet(keys);
                    }
                if(JdbcTemplate.this.this$0.isDebugEnabled())
                    JdbcTemplate.this.this$0.debug("SQL update affected " + rows + " rows and returned " + generatedKeys.size() + " keys");
                return new Integer(rows);
            }         
            {
                super();
            }
        }
);
        return result.intValue();
    }


查看相关PreparedStatement对象的具体执行源码
public int executeUpdate()
        throws SQLException
    {
        return executeUpdate(true, false);
    }

    protected int executeUpdate(boolean clearBatchedGeneratedKeysAndWarnings, boolean isBatch)
        throws SQLException
    {
        if(clearBatchedGeneratedKeysAndWarnings)
        {
            clearWarnings();
            batchedGeneratedKeys = null;
        }
        return executeUpdate(parameterValues, parameterStreams, isStream, streamLengths, isNull, isBatch);
    }

    protected int executeUpdate(byte batchedParameterStrings[][], InputStream batchedParameterStreams[], boolean batchedIsStream[], int batchedStreamLengths[], boolean batchedIsNull[], boolean isReallyBatch)
        throws SQLException
    {
        checkClosed();
//这个connection就是我们具体使用的连接的对象,具体实现就是jdbc的connection对象
        Connection locallyScopedConn = connection;
        if(locallyScopedConn.isReadOnly())
            throw SQLError.createSQLException(Messages.getString("PreparedStatement.34") + Messages.getString("PreparedStatement.35"), "S1009");
        if(firstCharOfStmt == 'S' && StringUtils.startsWithIgnoreCaseAndWs(originalSql, "SELECT"))
            throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), "01S03");
        if(results != null && !locallyScopedConn.getHoldResultsOpenOverStatementClose())
            results.realClose(false);
        com.mysql.jdbc.ResultSet rs = null;
        synchronized(locallyScopedConn.getMutex())
        {
            Buffer sendPacket = fillSendPacket(batchedParameterStrings, batchedParameterStreams, batchedIsStream, batchedStreamLengths);
            Stri