JdbcTemplate - 기본

박찬우·2024년 2월 5일

스프링 DB

목록 보기
25/53
post-thumbnail

설정

  • application.properties
# db 설정
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa
spring.datasource.password=

# sql 로그
logging.level.org.springframework.jdbc=debug

의존관계 주입

  • JdbcTemplate는 DataSource가 필요하다
  • 스프링 빈으로 등록하여 사용해도 됨
private final JdbcTemplate template;

public JdbcTemplateItemRepositoryV1(DataSource dataSource) {
	this.template = new JdbcTemplate(dataSource);
}

데이터 변경

  • template.update()
    • INSERT , UPDATE , DELETE SQL에 사용한다.
    • 반환 값은 int 인데, 영향 받은 로우 수를 반환한다.
String sql = "update item set item_name=?, price=?, quantity=? where id=?";

template.update(sql,
		updateParam.getItemName(),
		updateParam.getPrice(),
		updateParam.getQuantity(),
		itemId);

데이터 변경 - PK 자동생성

  • identity (auto increment) 방식같이 DB가 자동으로 PK을 생성하는 경우 사용
  • KeyHolder 사용
String sql = "insert into item(item_name, price, quantity) values (?,?,?)";
KeyHolder keyHolder = new GeneratedKeyHolder();

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);

long key = keyHolder.getKey().longValue();
item.setId(key);
return item;

데이터 조회 - 객체 변환

  • RowMapper 는 데이터베이스의 반환 결과인 ResultSet 을 객체로 변환한다
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;
	});
}

데이터 조회 - 단 건

  • template.queryForObject()
  • 결과 로우가 하나일 때 사용한다
  • 결과가 없으면 EmptyResultDataAccessException 예외가 발생한다.
  • 결과가 둘 이상이면 IncorrectResultSizeDataAccessException 예외가 발생한다.
String sql = "select id, item_name, price, quantity from item where id=?";

try {
	Item item = template.queryForObject(sql, itemRowMapper(), id);
	return Optional.of(item);
} catch (EmptyResultDataAccessException e) {
	return Optional.empty();
}

데이터 조회 - 여러 건

  • template.query()
  • 결과가 하나 이상일 때 사용한다
  • 결과가 없으면 빈 컬렉션을 반환한다.
String sql = "select id, item_name, price, quantity from item";

return template.query(sql, itemRowMapper());

데이터 조회 - 동적 쿼리

String itemName = cond.getItemName();
Integer maxPrice = cond.getMaxPrice();

String sql = "select id, item_name, price, quantity from item";
//동적 쿼리
if (StringUtils.hasText(itemName) || maxPrice != null) {
	sql += " where";
}

boolean andFlag = false;
List<Object> param = new ArrayList<>();
if (StringUtils.hasText(itemName)) {
	sql += " item_name like concat('%',?,'%')";
	param.add(itemName);
	andFlag = true;
}
if (maxPrice != null) {
	if (andFlag) {
		sql += " and";
	}
	sql += " price <= ?";
	param.add(maxPrice);
}
log.info("sql={}", sql);
return template.query(sql, itemRowMapper(), param.toArray());
profile
진짜 개발자가 되어보자

0개의 댓글