Класс NamedParameterJdbcTemplate привносит поддержку программирования инструкций JDBC с использованием именованных параметров, в отличие от программирования инструкций JDBC с использованием лишь классических аргументов-плейсхолдеров ( '?'). Класс NamedParameterJdbcTemplate обертывает JdbcTemplate и делегирует обернутому JdbcTemplate большую часть своей работы. В этом разделе описаны только те области функционирования класса NamedParameterJdbcTemplate, которые отличаются от самого JdbcTemplate – а именно программирование инструкций JDBC с использованием именованных параметров. В следующем примере показано, как использовать NamedParameterJdbcTemplate:

Java
// некоторый класс DAO с поддержкой JDBC...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int countOfActorsByFirstName(String firstName) {
    String sql = "select count(*) from T_ACTOR where first_name = :first_name";
    SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
    return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
Kotlin
private val namedParameterJdbcTemplate = NamedParameterJdbcTemplate(dataSource)
fun countOfActorsByFirstName(firstName: String): Int {
    val sql = "select count(*) from T_ACTOR where first_name = :first_name"
    val namedParameters = MapSqlParameterSource("first_name", firstName)
    return namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Int::class.java)!!
}

Обратите внимание на использование нотации именованного параметра в значении, присвоенном переменной sql, и соответствующем значении, которое подключено к переменной namedParameters (типа MapSqlParameterSource).

Кроме того, можно передать именованные параметры и соответствующие им значения экземпляру NamedParameterJdbcTemplate, используя стиль, основанный на Map. Остальные методы, открываемые NamedParameterJdbcOperations и реализуемые классом NamedParameterJdbcTemplate, следуют аналогичной схеме и здесь не рассматриваются.

В следующем примере показано использование стиля, основанного на Map:

Java
// некоторый класс DAO с поддержкой JDBC...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int countOfActorsByFirstName(String firstName) {
    String sql = "select count(*) from T_ACTOR where first_name = :first_name";
    Map<String, String> namedParameters = Collections.singletonMap("first_name", firstName);
    return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters,  Integer.class);
}
Kotlin
// некоторый класс DAO с поддержкой JDBC...
private val namedParameterJdbcTemplate = NamedParameterJdbcTemplate(dataSource)
fun countOfActorsByFirstName(firstName: String): Int {
    val sql = "select count(*) from T_ACTOR where first_name = :first_name"
    val namedParameters = mapOf("first_name" to firstName)
    return namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Int::class.java)!!
}

Одной из приятных особенностей, связанных с NamedParameterJdbcTemplate (и существующих в том же пакете Java), является интерфейс SqlParameterSource. Вы уже видели пример реализации этого интерфейса в одном из предыдущих фрагментов кода (класс MapSqlParameterSource). SqlParameterSource – это источник значений именованных параметров для NamedParameterJdbcTemplate. Класс MapSqlParameterSource представляет собой простую реализацию, которая является адаптером относительно java.util.Map, где ключами являются имена параметров, а значениями – значения параметров.

Другой реализацией SqlParameterSource является класс BeanPropertySqlParameterSource. Данный класс оборачивает произвольный JavaBean (то есть экземпляр класса, который соответствует соглашениям по JavaBean) и использует свойства обернутого JavaBean в качестве источника значений именованных параметров.

В следующем примере показан типичный JavaBean:

Java
public class Actor {
    private Long id;
    private String firstName;
    private String lastName;
    public String getFirstName() {
        return this.firstName;
    }
    public String getLastName() {
        return this.lastName;
    }
    public Long getId() {
        return this.id;
    }
    // сеттеры опущены...
}
Kotlin
data class Actor(val id: Long, val firstName: String, val lastName: String)

В следующем примере используется NamedParameterJdbcTemplate для возврата счётчика членов класса, показанного в предыдущем примере:

Java
// некоторый класс DAO с поддержкой JDBC...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int countOfActors(Actor exampleActor) {
    // обратите внимание на соответствие именованных параметров свойствам вышеупомянутого класса "Actor"
    String sql = "select count(*) from T_ACTOR where first_name = :firstName and last_name = :lastName";
    SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(exampleActor);
    return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
Kotlin
// некоторый класс DAO с поддержкой JDBC...
private val namedParameterJdbcTemplate = NamedParameterJdbcTemplate(dataSource)
private val namedParameterJdbcTemplate = NamedParameterJdbcTemplate(dataSource)
fun countOfActors(exampleActor: Actor): Int {
    // обратите внимание на соответствие именованных параметров свойствам вышеупомянутого класса "Actor"
    val sql = "select count(*) from T_ACTOR where first_name = :firstName and last_name = :lastName"
    val namedParameters = BeanPropertySqlParameterSource(exampleActor)
    return namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Int::class.java)!!
}

Помните, что класс NamedParameterJdbcTemplate обертывает классический шаблон JdbcTemplate. Если вам нужен доступ к экземпляру обернутого JdbcTemplate, чтобы получить доступ к функциональности, которая присутствует только в классе JdbcTemplate, можно использовать метод getJdbcOperations() для получения доступа к обернутому JdbcTemplate через интерфейс JdbcOperations.

См. также разделы "Оптимальные методы работы с JdbcTemplate", где приведены рекомендации по использованию класса NamedParameterJdbcTemplate в контексте приложения.