# [JdbcTemplate] RowMapper์— ๋Œ€ํ•ด
Study Repository

[JdbcTemplate] RowMapper์— ๋Œ€ํ•ด

by rlaehddnd0422

jdbctemplate์—์„œ select๋Š” query()์™€ queryForObject() ๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • query() ๋Š” ์ฟผ๋ฆฌ๋ฌธ ์‹คํ–‰์„ ํ†ตํ•ด ๊ฒฐ๊ณผ row๊ฐ€ ํ•˜๋‚˜์ผ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • queryForObject() ๋Š” ์ฟผ๋ฆฌ๋ฌธ ์‹คํ–‰์„ ํ†ตํ•ด ๊ฒฐ๊ณผ row๊ฐ€ ํ•˜๋‚˜ ์ด์ƒ์ผ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

query(), queryForObject() ๋ฉ”์†Œ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์•„๋ž˜ ์„ธ ๊ฐ€์ง€๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.

1. sql : ์ˆ˜ํ–‰ํ•  SQL ์ฟผ๋ฆฌ๋ฌธ 

2. newRowMapper() : RowMapper<Type> ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 

3. new Object[]{} : SQL ์ฟผ๋ฆฌ๋ฌธ์˜ ๋ฌผ์Œํ‘œ ๊ฐ’์— ์„ธํŒ…ํ•  ๊ฐ’ 

 

3๋ฒˆ์˜ ๊ฒฝ์šฐ ์ œ๋„ˆ๋ฆญ ํƒ€์ž…์— Type๊ณผ ๋งž๋Š” ์ต๋ช… ํด๋ž˜์Šค ๋กœ์ง ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

RowMapper<T> Interface

@FunctionalInterface
public interface RowMapper<T> {

   /**
    * Implementations must implement this method to map each row of data
    * in the ResultSet. This method should not call {@code next()} on
    * the ResultSet; it is only supposed to map values of the current row.
    * @param rs the ResultSet to map (pre-initialized for the current row)
    * @param rowNum the number of the current row
    * @return the result object for the current row (may be {@code null})
    * @throws SQLException if an SQLException is encountered getting
    * column values (that is, there's no need to catch SQLException)
    */
   @Nullable
   T mapRow(ResultSet rs, int rowNum) throws SQLException;

}
  • mapRow() ๋ฉ”์†Œ๋“œ๋Š” SQL ์‹คํ–‰ ๊ฒฐ๊ณผ๋กœ ๊ตฌํ•œ ResultSet์—์„œ ํ•œ ํ–‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์™€ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋งคํผ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • RowMapper ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์ž„์˜ ํด๋ž˜์Šค๋‚˜ ๋žŒ๋‹ค์‹์œผ๋กœ RowMapper์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ query() ๋ฉ”์†Œ๋“œ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

์ต๋ช… ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ 

@Override
public Optional<Item> findById(Long id) 
{
    String sql = "select id, item_name, price, quantity from item where id=?";
    try
    {
        Item item = template.queryForObject(sql,
                new RowMapper<Item>() {
                    @Override
                    public Item mapRow(ResultSet rs, int rowNum) throws SQLException {
                        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;
                    }
                }, id);
        return Optional.of(item);
    }catch(EmptyResultDataAccessException e)
    {
        return Optional.empty();
    }
}
  • findById() ๋ฉ”์†Œ๋“œ๋Š” jdbcTemplate์˜ query() ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ์ฟผ๋ฆฌ๋Š” ์ธ๋ฑ์Šค ํŒŒ๋ผ๋ฏธํ„ฐ(?)๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฌผ์Œํ‘œ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ธ ๊ฒฝ์šฐ ๋งŒ์•ฝ ์ด query() ๋ฉ”์†Œ๋“œ์˜ ์„ธ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์ธ ๊ฐ€๋ณ€์ธ์ž๊ฐ€ ๊ฐ’์ด ์—ฌ๋Ÿฌ๊ฐœ์ธ ๊ฒฝ์šฐ, ๊ฐ ๊ฐ’์„ ์ฝค๋งˆ๋กœ ๊ตฌ๋ถ„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ( id, price, .. ) 
  • mapRow ๋ฉ”์†Œ๋“œ๋Š” ResultSet์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์™€ Item ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฆฌํ„ดํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๋žŒ๋‹ค์‹์œผ๋กœ ๊ตฌํ˜„

@Override
public Optional<Item> findById(Long id) {
    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();
    }
}

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;
    });
}
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Item๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  rs(ResultSet)์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์™€ setter ์ฃผ์ž…ํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

queryForObject() Logic  

1. sql๊ณผ ๊ฐ€๋ณ€์ธ์ž(?)๋กœ ๋ฐ›์€ ๊ฐ’์„ ํ†ตํ•ด SQL ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑ ํ›„ ์‹คํ–‰ํ•˜์—ฌ ์ฟผ๋ฆฌ ์‹คํ–‰ ๊ฒฐ๊ณผ ResultSet์— ์ €์žฅ.

2. itemRowMapper์—์„œ ResultSet์„ ํ†ตํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด(Item) ๋ฆฌํ„ด.

(+ query()์˜ ๊ฒฝ์šฐ์—๋Š” ResultSet์— row๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ List<T> ๋กœ ๋ฆฌํ„ด) 

 

 

<์ฐธ๊ณ ์ž๋ฃŒ>

 

RowMapper (Spring Framework 6.0.7 API)

An interface used by JdbcTemplate for mapping rows of a ResultSet on a per-row basis. Implementations of this interface perform the actual work of mapping each row to a result object but don't need to worry about exception handling. SQLExceptions will be c

docs.spring.io

 

 

RowMapper์— ๋Œ€ํ•ด!

์•ž์—์„œ ๋งํ•˜๊ธธ queryForObject์˜ ๋ฐ˜ํ™˜ํ˜•์€ ๋ฐ์ดํ„ฐํ˜•๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ–ˆ๋‹ค.ํ•˜์ง€๋งŒ ๋ง๋„ ์•ˆ๋œ๋‹ค.๊ทธ๋Ÿผ "SELECT \* FROM USER" ๊ตฌ๋ฌธ์œผ๋กœ User ๊ฐ์ฒด ์ž์ฒด๋ฅผ ๋ฐ˜ํ™˜๋ฐ›๋Š”๊ฑด ํฌ๊ธฐํ•ด์•ผ ํ•˜๋Š”๊ฑธ๊นŒ?๊ทธ๊ฑธ ์œ„ํ•ด์„œ ํ•„์š”ํ•œ ๊ฒƒ์ด

velog.io

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ