스프링 db2 - JdbcTemplate 사용 정보

2023. 1. 31. 20:47spring/db

1/31

 

기본 JdbcTemplate

private JdbcTemplate template;

//데이터 소스 주입
public JdbcTemplateItemRepositoryV1(DataSource dataSource) {
    this.template = new JdbcTemplate(dataSource);
}

* save / SQL query 문장 (PK : id , 데이터베이스에서 자동 생성)

public Item save(Item item) {
    String sql = "insert into item(item_name, price, quantity) values (?,?,?)";

- 순서대로 파마티러를 전달 받는다.

KeyHolder keyHolder = new GeneratedKeyHolder();
//데이터베이스에 insert 후 데이터베이스에서 지정한 id값을 얻어오기
template.update(connection ->{
    PreparedStatement pstmt = connection.prepareStatement(sql, new String[]{"id"});
    pstmt.setString(1, item.getItemName());
    pstmt.setInt(2, item.getPrice());
    pstmt.setInt(3, item.getQuantity());
    return pstmt;
}, keyHolder);

- keyHolder 필요

- template.update(커넥션 람다식 , KeyHolder)을 통해 파라미터에 값을 넣고 데이터베이스에 저장한다.

 

* findById / PK 값으로 한 개 검색(찾기)

 

-template.queryForObject(SQL query문장 , RowMapper , PK값)

- RowMapper -> 데이터베이스에서 얻은 값들을 도메인 객체 상태로 반환받기 위한 클래스

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

 


NamedParameterJdbcTemplate

 

- 순서대로 값을 대입받던 파라미터들을 이름으로 대입하게 바꾸었다.

public Item save(Item item) {
    String sql = "insert into item(item_name, price, quantity) " +
            "values (:itemName, :price, :quantity)";

 

* template.update( 파라미터 : SQL query문장, SqlParameterSource , keyValue)

 

* SqlParameterSource

 

1. BeanPropertySqlParameterSource ( 파라미터 : 객체)

파라미터로 전달받은 객체에서 자바에서 제공하는 규약에 따라 [ex) getName -> name]  쿼리문장에 전달할 수 있는 값들을 알아서 전달해준다.

SqlParameterSource param = new BeanPropertySqlParameterSource(item);
KeyHolder keyHolder = new GeneratedKeyHolder();
template.update(sql, param, keyHolder);

 

 

2. MapSqlParameterSource().addValue

Map이랑 비슷하다. key , value 형태로 값을 저장해서 파라미터로 만들어준다.

SqlParameterSource param = new MapSqlParameterSource().addValue("itemName", updateParam.getItemName())
        .addValue("price", updateParam.getPrice())
        .addValue("quantity", updateParam.getQuantity())
        .addValue("id", itemId);

3. Map

Map<String, Object> param = Map.of("id", id);

Map도 SqlParameterSource로 사용이 가능하다.

 

 

* queryForObject(SQL query 문장, 파라미터 , RowMapper )

 

4. BeanPropertyRowMapper.newInstance(파라미터 : 클래스)

private RowMapper<Item> itemRowMapper() {
    return BeanPropertyRowMapper.newInstance(Item.class);
}

도메인 객체 클래스를 파라미터로 전달해서 아주 간단하게 맵핑을 할 수 있다.


SimpleJdbcInsert

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", "quantity"); //생략가능
    }

* withTableName ( 객체 명 ) 

* usingGeneratedKeyColumns( PK )

* usingColums(저장할 변수명들)

 

- 저장의 경우 거의 비슷한 유형이라서 미리 기본적인 정보를 저장해놓고 함수로 저장할 수 있게끔 구현되어 있다.

 

* 기존 insert 코드

public Item save(Item item) {
    String sql = "insert into item(item_name, price, quantity) " +
            "values (:itemName, :price, :quantity)";

    SqlParameterSource param = new BeanPropertySqlParameterSource(item);
    KeyHolder keyHolder = new GeneratedKeyHolder();
    template.update(sql, param, keyHolder);

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

* SimpleJdbcInsert 사용 코드

public Item save(Item item) {
    SqlParameterSource param = new BeanPropertySqlParameterSource(item);
    Number key = jdbcInsert.executeAndReturnKey(param);
    item.setId(key.longValue());
    return item;
}

jdbcInsert.executeAndReturnKey 에 파라미터만 넘기면 KeyHolder를 바로 받고 저장까지 가능하다.