NamedParameterJdbcTemplate
는 인터페이스 NamedParameterJdbcOperations
의 구현체다.오늘 알아 볼 것은 update인데, 반환 값을 보면 int다. 하지만 이 int가 무엇을 뜻하는지
NamedParameterJdbcTemplate
에선 확인 할 수 없다.@Override public int update(String sql, Map<String, ?> paramMap) throws DataAccessException { return update(sql, new MapSqlParameterSource(paramMap)); }
대신 인터페이스인
NamedParameterJdbcOperations
에서 update의 반환값이 무엇을 뜻하는지 확인 할 수 있다. 반환값 int는 update 쿼리를 통해 영향을 받은 row들의 갯수다./** * Issue an update via a prepared statement, binding the given arguments. * @param sql the SQL containing named parameters * @param paramSource container of arguments and SQL types to bind to the query * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update */ int update(String sql, SqlParameterSource paramSource) throws DataAccessException;
이제 아래의 insert 메서드를 보자.
@Override public Optional<Voucher> insert(Voucher voucher) { try { var executeUpdate = jdbcTemplate.update("INSERT INTO vouchers(" + "voucher_id, name, type, discount_num, created_at) " + "VALUES (UUID_TO_BIN(:voucherId), :name, :type, :discountNum, :createdAt)", toParamMap(voucher)); if (executeUpdate != 1) { return Optional.empty(); } return Optional.of(voucher); } catch (DuplicateKeyException e) { logger.error("Failed insert", e); return Optional.empty(); } }
바우처를 저장하는 메서드인데, 저장에 성공했다면 하나의 row에만 영향을 줬을 것이다. 그렇기 때문에 해당 update의 반환값은 1 또는 0 이다. 단순히 1이 아닐 경우에만 예외적으로 빈 Optional를 반환하는 코드를 작성하면 된다.
만약 여러개의 row에 업데이트를 하면 어떨까?
@Override public int delete(Wallet wallet) { var executeUpdate = jdbcTemplate.update( "DELETE FROM wallets WHERE wallet_id = UUID_TO_BIN(:walletId)", toParamMap(wallet)); return executeUpdate; }
위 코드는 wallet_id와 voucher_id가 PK인 복합키를 가지고 있는 테이블에서 delete를 수행하는 코드다. wallet_id만으로 삭제를 진행한다면 여러 개의 row가 삭제될 가능성이 있다.
그렇기 때문에 반환 값으로 영향을 받은 row들을 반환해준다.
정리
- update의 경우 에러가 발생하면
DataAccessException
를 발생시킨다.
- 쿼리가 정상적으로 실행됬을 경우 쿼리를 통해 영향을 받은 row의 수를 확인 할 수 있다.