Search code examples
spring-bootjdbc

how is connection injected into the inline function of jdbctemplate.query?


I saw code as the following,

List<UploadedDocument> docs = jdbcTemplate.query(
                connection -> {
                PreparedStatement stmt = connection.prepareStatement(sql);
                stmt.setString(1, userName);
                return stmt;
            },
            this::getDocumentsFromResultSet
    );

I knew connection should database connection but could not find how it's created. It's not declared in the method or anywhere in the class.


Solution

  • It's basically no different from other JdbcTemplate methods where a query is executed without you explicitly needing to create or acquire a connection: Spring handles the creation/acquisition of the connection for you; it's made available to JdbcTemplate by Spring.

    (The connection may have been created as part of a DB connection pool, when your app starts. But either way, all you have to provide are the connection properties.)


    Looking more closely at your specific example, there is actually an explicit mention of a connection instance.

    So, why is that?

    It's because of the lambda expression used in the example.

    The specific query method in the question is:

    query(PreparedStatementCreator psc,  ResultSetExtractor<T> rse)
    

    Reference.

    (At least, I think that's a ResultSetExtractor - I can't see the implementation of this::getDocumentsFromResultSet. But that is not relevant here.)

    Ignoring the ResultSetExtractor, if we look at PreparedStatementCreator, we see that is a functional interface - which is why we can use the lambda expression shown in the question.

    The specific method is for this functional interface is:

    createPreparedStatement(Connection con)
    

    That is where the connection object is provided (by Spring):

    The Javadoc states:

    This interface creates a PreparedStatement given a connection, provided by the JdbcTemplate class.

    You get to see that reference - but you don't create it. You just make use of it to build your PreparedStatement.


    It's possible the JdbcTemplate was constructed using a DataSource "to obtain connections from".

    But again, you would not see any code in the JdbcTemplate relating to the creation of any connections, or acquiring a connection from the pool (if you are using a pool)>


    Extra Note

    Looking in the source code for JdbcTemplate, you can see where instances of that class acquire their database connection. Here is one example:

    Connection con = DataSourceUtils.getConnection(obtainDataSource());
    

    See here.