В своём предыдущем посте я описал работу с JdbcTemplate на примере простого DAO-класса. Возможностей JdbcTemplate вполне хватает, что бы сделать работу с базами данными немного проще. Но использование вопросительного знака в качестве плейсхолдера для параметра запроса не всегда удобно, особенно, когда речь идёт о работе с таблицами, имеющими большое количество колонок. В этом случае удобнее будет использовать класс NamedParameterJdbcTemplate, который позволяет использовать именованные параметры в SQL-запросах.
Хороший пример, в котором может пригодиться NamedParameterJdbcTemplate — удаление списка записей по идентификаторам. Добавим такой метод в интерфейс:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public interface PersonRepository { RowMapper<Person> ROW_MAPPER = (ResultSet resultSet, int rowNum) -> { return new Person(resultSet.getString("id"), resultSet.getString("name"), resultSet.getString("email")); }; List<Person> findAll(); Person findOne(String id); Person save(Person person); int delete(String id); int deleteAll(Collection<String> ids); } |
Теперь напишем тест, который должен будет пройти новый метод:
1 2 3 4 5 6 7 8 9 10 11 |
public class TestPersonRepository { // лишний код опущен @Test public void testDeleteAll() { Assert.assertEquals(2, personRepository.deleteAll(Arrays.asList("jack-daniels", "george-dickel"))); Assert.assertEquals(0, personRepository.deleteAll(Arrays.asList("jack-daniels", "george-dickel"))); } } |
Займёмся реализацией. У NamedParameterJdbcTemplate есть три конструктора: без аргументов, с аргументом типа javax.sql.DataSource или с аргументом типа org.springframework.jdbc.core.JdbcTemplate. Добавим нашему DAO-классу всё необходимое:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@Component public final class PersonRepositoryImpl implements PersonRepository { private final JdbcTemplate jdbcTemplate; private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; @Autowired public PersonRepositoryImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); } @Override public int deleteAll(Collection<String> ids) { return namedParameterJdbcTemplate.update("delete from person where id in (:ids)", Collections.singletonMap("ids", ids)); } // лишний код опущен } |
В качестве контейнера свойств запроса можно так же передавать объект одного из классов, реализующих SqlParameterSource.