해결된 질문
작성
·
244
0
강의에서 update부분을
new BeanPropertySqlParameterSource()
로 변경해서 사용해 보았는데 수정이 정상적을 이루어 졌습니다.
I’d가 어떻게 자동으로 매핑이 되는건가요?
답변 1
0
아 제가 Config에 빈 등록할때 리포지토리를 V2로 안바꾸고 실행해서 적용이 안되었던거였네요 ;;; ㅎㅎV2로 변경하고 나니 오류 발생합니다.
그런데 강의자료로 올려주신pdf에는 V2에 @Repository어노테이션에 붙어있는데
개발자가 직접 빈 등록을 하였으면 @Repository 어노테이션이 필요 없는것 아닌가요? 영상에서는 안 붙여 주셨는데 강의자료에 따로 붙어있는 이유가 있나요?
그리고 h2데이터베이스 클라이언트에서 item테이블의 튜플들을 모두 지우고 서버를 다시 시작했는데 id가 1번부터 시작하지 않고 지우기전 id의 다음순서의 id로 시작을 하는데 id는 왜 1번부터 시작하지 않는건가요? 1번부터 시작하게 하려면 어떻게 해야하나요?
예리한 질문이십니다 😀
@Repository를 사용하면 JDBC 예외를 스프링의 데이터 계층 예외로 변환해주는 AOP가 적용되는데요, JdbcTemplate은 JDBC 예외를 스프링의 데이터 계층 예외로 변환해주는 기능을 내부에 포함하고 있어서 사용하지 않았다고 하시네요.
메뉴얼과의 차이는 잘 모르겠습니다.
https://www.inflearn.com/questions/1211018/repository-%EC%82%AC%EC%9A%A9-%EC%B0%A8%EC%9D%B4%EC%A0%90
h2 시퀀스를 초기화 하는 방법은 다음 링크를 참고해주세요^^
@Slf4j public class JdbcTemplateItemRepositoryV2 implements ItemRepository { // private final JdbcTemplate template; private final NamedParameterJdbcTemplate template; // 파라미터 바인딩을 순서가 아닌 이름으로 하게 해줌 public JdbcTemplateItemRepositoryV2(DataSource dataSource) { this.template = new NamedParameterJdbcTemplate(dataSource); } @Override public Item save(Item item) { String sql = "insert into item(item_name, price, quantity) " + "values (:item_name, :price, :quantity)"; // 이름기반의 파라미터가 필요 // item객체의 필드들을 이름으로 파라미터를 만든다 // SqlParameterSource param = new BeanPropertySqlParameterSource(item); Map<String, Object> param = Map.of( "item", item.getItemName(), "price", item.getPrice(), "quantity", item.getQuantity() ); KeyHolder keyHolder = new GeneratedKeyHolder(); template.update(sql, (SqlParameterSource) param, keyHolder); long key = keyHolder.getKey().longValue(); item.setId(key); return item; } @Override public void update(Long itemId, ItemUpdateDto updateParam) { String sql = "update item set item_name = :item_name, price = :price, quantity = :quantity where id = :id"; // SqlParameterSource param = new MapSqlParameterSource() // .addValue("itemName", updateParam.getItemName()) // .addValue("price", updateParam.getPrice()) // .addValue("quantity", updateParam.getQuantity()) // .addValue("id", itemId); SqlParameterSource param = new BeanPropertySqlParameterSource(updateParam); template.update(sql, param); } @Override public Optional<Item> findById(Long id) { String sql = "select id, item_name, price, quantity from item where id = :id"; try { Map<String, Object> param = Map.of("id", id); // SqlParameterSource param = new BeanPropertySqlParameterSource(id); Item item = template.queryForObject(sql, param, itemRowMapper()); return Optional.of(item); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } } @Override public List<Item> findAll(ItemSearchCond cond) { Integer maxPrice = cond.getMaxPrice(); String itemName = cond.getItemName(); SqlParameterSource param = new BeanPropertySqlParameterSource(cond); String sql = "select id, item_name, price, quantity from item"; //동적 쿼리 if (StringUtils.hasText(itemName) || maxPrice != null) { sql += " where"; } boolean andFlag = false; if (StringUtils.hasText(itemName)) { sql += " item_name like concat('%',:itemName,'%')"; andFlag = true; } if (maxPrice != null) { if (andFlag) { sql += " and"; } sql += " price <= :maxPrice"; } log.info("sql={}", sql); return template.query(sql, param, itemRowMapper()); } private RowMapper<Item> itemRowMapper() { // return (rs, rowNum) -> { // Item item = new Item(); // item.setId(rs.getLong("id")); // item.setItemName(rs.getString("item_name")); // item.setPrice(rs.getInt("price")); // item.setQuantity(rs.getInt("quantity")); // return item; // }; return BeanPropertyRowMapper.newInstance(Item.class); //camel 변환 지원 } }
해당 코드를 실행하였습니다.
첫 실행시 아이템 이름을 수정하니
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon May 13 13:24:51 KST 2024
There was an unexpected error (type=Internal Server Error, status=500).
로 이동하여 수정이 안되는데 같은 아이템의 가격, 수량을 수정하는것은 정상적으로 동작합니다.
1, 2번 아이템이 특히 이렇게 동작하였고 나머지 아이템들은 이름, 가격, 수량을 수정하여도 정상적으로 반영이 됩니다.