It would be great if JdbcOperations or JdbcTemplate could be enhanced to support String Template.

The easiest way to support this is to provide a StringTemplate.Processor<PreparedStatementCreator, DataAccessException> implementation, ideally as a constant somewhere. Something like this can already be achieved today with PreparedStatementCreatorFactory but is a bit awkward due to the need to explicitly register SqlParameter with type TYPE_UNKNOWN.

Example:

@Transactional
@SpringJUnitConfig(H2Configuration.class)
class JdbcTemplateTests {

  private static final StringTemplate.Processor<PreparedStatementCreator, DataAccessException> SQL = new PreparedStatementCreatorTemplateProcessor();

  @Autowired
  private DataSource dataSource;

  private JdbcOperations jdbcTemplate;

  @BeforeEach
  void setUp() {
    this.jdbcTemplate = new JdbcTemplate(this.dataSource);
  }

  @Test
  void query() {
    String name = "ok";
    List<String> names = this.jdbcTemplate.query(SQL."""
            SELECT \{name}
            FROM dual
          """, (rs, i) -> rs.getString(1));
    assertEquals(List.of(name), names);
  }

  static final class PreparedStatementCreatorTemplateProcessor implements StringTemplate.Processor<PreparedStatementCreator, DataAccessException> {

    public PreparedStatementCreator process(StringTemplate st) {
      String sql = String.join("?", st.fragments());
      PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(sql);
      List<Object> parameters = st.values();
      for (Object parameter : parameters) {
        factory.addParameter(new SqlParameter(JdbcUtils.TYPE_UNKNOWN));
      }
      return factory.newPreparedStatementCreator(parameters);
    }
  }

}

It's still a bit awkward as only methods accepting PreparedStatementCreator would work.

Comment From: simonbasle

Thanks for the suggestion @marschall. Given that String Templates are still a preview feature in Java 21 and that Spring 6's baseline is Java 17, it would be a challenge to integrate String Templates into the API directly at this stage.

Do you feel that your proposed PreparedStatementCreatorTemplateProcessor is too much boilerplate for your codebase?

Btw, one thing that I think could be improved wrt TYPE_UNKNOWN would be using StatementCreatorUtils like so:

factory.addParameter(new SqlParameter(StatementCreatorUtils.javaTypeToSqlParameterType(parameter.getClass())));

Comment From: marschall

Thanks for the suggestion @marschall. Given that String Templates are still a preview feature in Java 21 and that Spring 6's baseline is Java 17, it would be a challenge to integrate String Templates into the API directly at this stage.

Fair enough. Maybe something that can be visited again should String Templates become fully supported.

Do you feel that your proposed PreparedStatementCreatorTemplateProcessor is too much boilerplate for your codebase?

For our code base no. We already have quite a bit of custom JDBC support code and that will fit right in. But I do think it's not ideal when this snipped has to be copy an pasted in a lot of projects, especially with your improvement to TYPE_UNKNOWN.

Comment From: simonbasle

One thing we could do to anticipate support is provide code from that process method as a static utility method, albeit with a different signature which doesn't involve StringTemplate but is easy enough to adapt...

But still, I'm not keen on providing something based on a Preview Feature. Sure, it's not Experimental but depending on community feedback things could still change.

So I'm inclined to close this one for now. Would you be willing to reopen an issue when String Template feature is officially released in Java @marschall ?

Comment From: marschall

So I'm inclined to close this one for now. Would you be willing to reopen an issue when String Template feature is officially released in Java @marschall ?

Sure

Comment From: simonbasle

This will need to be revisited once the String Template feature is GA in Java, at which point there should be a way for Spring to provide supporting methods to reduce the boilerplate in creating a StringTemplate.Processor (or even provide such a processor depending on the java baseline at the time).

Comment From: snicoll

We could also reuse this issue with a ping to ask us to reconsider.