Spring Jdbc Template, SimpleInsert

꾸준하게 달리기~·2023년 7월 3일
0

스프링 + 자바

목록 보기
4/20
post-thumbnail

Spring Jdbc Template

Spring JDBC Template은 JDBC를 편리하게 사용하기 위한 도구이다.

어떤 역할을 하냐면,

  • 커넥션 획득
    데이터베이스와의 연결을 생성하고 관리하기 위해 커넥션 획득.
    (커넥션이란, 데이터베이스와의 연결을 나타내는 객체)

  • Statememt 준비 및 실행
    실행할 SQL문 생성, 필요한 매개변수 설정.

  • 결과 처리 위한 루프 실행
    SQL문의 실행 결과 처리 위해 반복문 실행.

  • 트랜잭션 위한 커넥션 동기화
    Spring의 트랜잭션 관리 기능과 통합하여 트랜잭션 처리하도록, 커넥션 동기화 제공.

  • 예외 변환
    DB 작업중 발생하는 SQLException과 같은 에러를 DataAccessExeption과 같은 에러로 변환.
    (변환된 에러를 런타임 에러로 처리하여 필요한 경우 롤백 가능.)

의 역할을 한다.

JdbcTemplate 사용법

의존성 추가

//JdbcTemplate 추가
implementation 'org.springframework.boot:spring-boot-starter-jdbc'

DataSouce 주입

DataSource란?
데이터베이스와의 연결을 관리하는 인터페이스.
데이터베이스에 접속하고 커넥션을 관리하기 위한 기능을 제공.
(다양한 DB들에 대한 드라이버 지원, 트랜잭션, 커넥션 관리 가능한 인터페이스)

// DataSource를 주입하기 위해선, DataSource 스프링 빈으로 등록되어있어야 함.
// 앞으로 계~속해서 바로 아래의 jdbcTemplate 객체를 사용할 예정!
private final JdbcTemplate jdbcTemplate;

public JdbcTemplateItemRepository(DataSource dataSource) {
	this.jdbcTemplate = new JdbcTemplate(dataSource);
}




쿼리 작성 및 실행


queryForObject()

// 조회 대상이 객체가 아닌, VARCHAR이나 INT같은 데이터라면, 아래와 같은식으로 사용 가능.
int 행의개수 = jdbcTemplate.queryForObject("select count(*) from 테이블명",Integer.class);
// String을 조회할 때는 아래와 같이 사용할 수도 있다.

String id_1212L_lastName = jdbcTemplate.queryForObject(
"select last_name from 테이블명 where id = 1212L);
//preparedStatement ("?")를 이용해 파라미터 바인딩도 가능
int 조씨성행의개수 = jdbcTemplate.queryForObject(
"select count(*) from 테이블명 where first_name = ?", Integer.class, "Joe"); //? 에 Joe를 바인딩.

RowMapper클래스란?
(데이터베이스의 반환 결과인 ResultSet을 객체로 변환해주는 클래스.)


mapRow() 매서드는,
ResultSet rs에 결괏값을 담아와 사용자가 원하는 객체에 담는 매서드.

(아래의 코드에서 내가 원하는 객체는가 의미하는 내용은,
Item 클래스의 객체.)

// 쿼리 날리기 (아이템 테이블 싹다 꺼내와라)
ResultSet rs = stat.excuteQuery("SELECT * FROM Item");

public Item mapRow(ResultSet rs, int rowNum) throws SQLException {

    // ResultSet 값을 Item 객체에 저장, 
    // Item객체는 JdbcTemplate관련 객체가 아니라 내가 만들어낸 클래스.
    // 해당 클래스는 id, itemName, price를 멤버변수로 가짐.
    // getInt(columnName), getString(columnName)은 
    // columnName에 해당하는 열의 Int값이나 String값을 가져옴

    Item item = new Item();
    item.setId(rs.getLong("id"));
    item.setItemName(rs.getString("item_name"));
    item.setPrice(rs.getInt("price"));
    
    // item 반환
    return item;
};

query()

위처럼 mapRow()를 사용해서 하나의 객체만 반환할 수도 있고,
query()를 이용해서 여러건을 조회할 수도 있다.
query() 이용도 RowMapper 객체를 이용해야 한다.

//이때도 역시 RowMapper를 이용해야 한다.

private final RowMapper<Item> itemRowMapper = (resultSet, rowNum) -> {
    Item item = new Item();
    item.setId(rs.getLong("id"));
    item.setItemName(rs.getString("item_name"));
    return item;
};

public List<Item> findAllItems() {
    return this.jdbcTemplate.query("select id, item_name from 테이블명", itemRowMapper); 
//바로 위의 itemRowMapper객체가 위에서 말한 RowMapper객체를 사용해야 한다는 내용.

update()

INSERT, UPDATE, DELETE 등 데이터를 변경하고 싶을 때는 update() 메서드를 사용.

//등록
jdbcTemplate.update("insert into 테이블명 (id, item_name) values (?, ?)", 5276L, "노트북");

//수정
jdbcTemplate.update("update 테이블명 set item_name = ? where id = ?", "노트북", 5276L);

//삭제
jdbcTemplate.update("delete from 테이블명 where id = ?", Long.valueOf(item_id));

레퍼런스
https://code-lab1.tistory.com/277


SimpleJdbcInsert

위에서,
JdbcTemplate 클래스를 이용해서 DB와의 커넥션을 만들기 위해서는
쿼리문을 작성했다.

하지만!
SimpleJdbcInsert는 그 쿼리마저도 필요 없게 하기 위해 탄생한 클래스이다.

SimpleJdbcInsert 사용법

DataSource 주입 (JdbcTemplate와 별반 다르지 않다.)

private final SimpleJdbcInsert simpleJdbcInsert;

    public SimpleInsert(DataSource dataSource) {
        return this.simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
                .withTableName("items");
    }

해당 매서드를 위와 같이
.withTableName("items") 를 사용해서
마쳐도 되고,

.usingGeneratedKeyColumns("id");
를 추가해준 후 데이터를 삽입할 때

executeAndReturnKey() 를 이용하여
자동으로 생성된 키 값을 반환하도록 할 수 있다.
무슨말이지..? 싶으면 바로 아래에서 코드를 보며 설명하겠다.

Map방식 사용해서 쿼리문 없이 정보 꺼내기

public Item insertWithMap(Item item) {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("id", item.getId());
        parameters.put("item_name", item.getitemName());
        Long itemId = simpleJdbcInsert.executeAndReturnKey(parameters);
        //여기를 말한 것 이었습니다!
        //usingGeneratedKeyColumns(“id”) 라고 했으니,
        //executeAndReturnKey 매서드 사용시
        //아이디 칼럼 값이 나오게 됩니다!
        return new Item(itemId, item.getItemName());
    }

BeanPropertySqlParameterSource방식 이용해서 쿼리문 없이 정보 꺼내기

해당 방식은,
Map과 같은 방식은 필드가 많아지면 파라미터에 많은 내용을 추가해야 하니까, (parameters.put)
작업할 내용이 많아지게 된다.
해당 이슈가 생길때 사용해주면 좋다.

public Item insertWithBeanPropertySqlParameterSource(Item item) {
    SqlParameterSource parameters = 
                 new BeanPropertySqlParameterSource(item);
    long id =
           simpleJdbcInsert.executeAndReturnKey(parameters).longValue();
    return new Item(id, item.getItemName());
}

레퍼런스
https://mungto.tistory.com/446

profile
반갑습니다~! 좋은하루 보내세요 :)

0개의 댓글