Search
Duplicate
📒

[Database Study] 04-5. JdbcTemplate - 이름지정 파라미터, SimpleJdbcInsert

상태
미진행
수업
Database Study
주제
JDBC
4 more properties
참고

JdbcTemplate - 이름 지정 파라미터

NOTE
JdbcTemplate을 기본적으로 사용하면 파라미터를 순서대로 바인딩한다
String sql = "update item set item_name=?, price=?, quantity=? where id=?"; template.update(sql, itemName, price, quantity, itemId);
Java
복사
여기서는 itemName, price, quantity, idsql에 순서대로 바인딩된다.
그런데 문제는 파라미터 순서를 바꾸면 심각한 문제가 발생하게 된다. (다른게 맵핑됨)
quantity가 price로 , price가 quantity로 잘못 맵핑됨..
이러한 모호성을 제거하기 위해 NamedParameterJdbcTemplate를 사용한다!

NamedParameterJdbctemplate (이름 지정 바인딩)

NOTE
NamedParameterJdbctemplate는 파라미터를 바인딩 하는 기능을 제공한다

NamedParameterJdbctemplate 생성

private final NamedParameterJdbcTemplate template; public JdbcTemplateItemRepositoryV2(DataSource dataSource) { this.template = new NamedParameterJdbcTemplate(dataSource); }
Java
복사
NamedParameterJdbctemplate는 JdbcTemplate와 동일한 형태로 생성됨

NamedParameterJdbctemplate 사용방법

// JdbcTemplate String sql = "insert into item(item_name, price, quantity) values (?,?,?)"; template.update(connection -> { PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"}); ps.setString(1, item.getItemName()); ps.setInt(2, item.getPrice()); ps.setInt(3, item.getQuantity()); return ps;}, keyHolder);
Java
복사
JdbcTemplate 사용방법
// NamedParameterJdbcTemplate String sql = "insert into item(item_name, price, quantity) values (:itemName,:price,:quantity)"; BeanPropertySqlParameterSource param = new BeanPropertySqlParameterSource(item); template.update(sql, param, keyHolder);
Java
복사
NamedParameterJdbcTemplate 사용방법
JdbcTemplate는 파라미터 바인딩을 위해 ?를 사용하고, PreparedStatement에서 직접 세팅해주었다
NamedParameterJdbcTemplatePreparedStatement를 사용하는 대신, :[이름]을 지정하고 Parameter Map을 넘겨주는 방식으로 처리가 된다.

Parameter Map 구현방법 3가지

NOTE

Map

Map<String, Long> param = Map.of("id", id); Item item = template.queryForObject(sql, param,itemRowMapper()); return Optional.of(item);
Java
복사
단순히 Map을 사용하면 된다.

BeanPropertySqlParameterSource (권장)

@Override public List<Item> findAll(ItemSearchCond cond) { ... SqlParameterSource param = new BeanPropertySqlParameterSource(cond); ... }
Java
복사
BeanPropertySqlParameterSource에 DB에 넣을 객체(item)을 전달해준다
자바 빈 프로퍼티 규약을 통해서 자동으로 파라미터 객체 생성
ex) getItemName() → itemName()
단 Dto에 없는 값이 있을경우에는, 사용이 불가능하다

MapSqlParameterSource

String sql = "update item set item_name=:itemName, price=:price, quantity=:quantity where id=:id"; //NamedParameterJdbcTemplate을 사용하면서 다음과 같이 해결함. MapSqlParameterSource param = new MapSqlParameterSource() .addValue("itemName", updateParam.getItemName()) .addValue("price", updateParam.getPrice()) .addValue("quantity", updateParam.getQuantity()) .addValue("id", itemId);
Java
복사
현재 DTO는 id가 존재하지 않는다
DTO에 없는 값을 등록할 때 유용한다.

SimpleJdbcInsert

NOTE
JdbcTemplate은 INSERT SQL을 직접 작성하지 않아도 되도록, ‘SimpleJdbcInsert’라는 기능을 제공한다.

SimpleJdbcInsert - 사용

NOTE
public class JdbcTemplateItemRepositoryV3 implements ItemRepository { private final NamedParameterJdbcTemplate template; private final SimpleJdbcInsert jdbcInsert; public JdbcTemplateItemRepositoryV3(DataSource dataSource) { this.template = new NamedParameterJdbcTemplate(dataSource); this.jdbcInsert = new SimpleJdbcInsert(dataSource) .withTableName("item") .usingGeneratedKeyColumns("id"); //.usingColumns("item_name", "price", "quantitiy") // 생략가능 } @Override public Item save(Item item) { SqlParameterSource param = new BeanPropertySqlParameterSource(item); Number key = jdbcInsert.executeAndReturnKey(param); item.setId(key.longValue()); return item; }
Java
복사
사용 코드
withTableName : 데이터를 저장할 테이블 명을 지정
usingGeneratedKeyColumns : Key를 생성하는 PK컬럼명을 지정한다
usingColumns : INSERT SQL에 사용할 컬럼을 지정한다, 특정한 값만 저장하고 싶을 때 사용하며 생략이 가능함