스프링 부트에서 JDBC Template 사용하기(MySQL)

권하준·2024년 5월 22일
1

Spring Boot

목록 보기
11/14

스프링 부트와 MySQL 연동에 관련된 글은 이전 포스팅을 참고하자

이번에는 연동한 DB를 스프링 부트 프로젝트 안에서 사용하는 방법을 정리하려고 한다.

스프링 부트에서 DB를 사용하는 방식은 아래와 같은 여러가지가 있다.

  • JDBC
  • JDBC Template
  • JPA
  • 등등

요즘에는 JPA가 가장 많이 쓰이는 것 같은데, 나는 우선 SQL 쿼리 짜는걸 연습할 겸 JDBC Template을 사용하였다. JDBC Template은 JDBC에 비해 복잡한 설정 코드를 작성하지 않아도 된다는 장점이 있다.

그럼 JDBC 사용 방법을 알아보자.

Repository 클래스 생성 및 의존관계 설정

  • 우선 스프링 부트 프로젝트에서, DB와의 연결을 책임질 Repository 클래스를 만들어 준다.
  • 의존 관계 설정
    • Repository안에서 JDBC Template를 사용하기 위해 JdbcTemplate 멤버를 사용해야함
      • JdbcTemplateDataSource를 의존하기 때문에, 생성자에서 이에 대한 의존 관계를 주입해준다.
private final JdbcTemplate jdbcTemplate;

    @Autowired
    public JdbcUserRepository(DataSource dataSource){
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

데이터 조작 문법(Insert, Update, Delete)

  • JDBC Template에서는 update(Query, Parameters, ...) 메소드를 사용하여 데이터를 조작한다. 사용 예시는 아래와 같다.
public User addUser(User user) {
        String query = "INSERT INTO USER(ID, PW) VALUES (?, ?);";
        jdbcTemplate.update(query, user.getId(), user.getPw());
        return user;
    }
  1. SQL 쿼리를 작성해준다. 여기서 매개변수로 넘길 값은 ?를 활용한 파라미터 형태로 작성한다.
  2. JdbcTemplate.update()의 매개변수로 쿼리 문자열을 넘겨준다. 이후 해당 쿼리의 매개변수를 순차적으로 함께 넘겨준다.

위와 같은 과정으로 매우 간단하게 데이터를 조작할 수 있다.

데이터 출력 문법(SELECT)

  • 데이터를 출력하는 경우에는, DB에서 검색한 값을 Java 객체로 감싸주는 작업이 필요하다. 해당 작업을 위해 RowMapper 메소드를 작성 후 사용한다.
  • 데이터를 출력할 때는 query(Query, RowMapper, Parameters, ...)를 사용한다.
  • 예시는 아래와 같다.

RowMapper

RowMapper<User> userRowMapper() {
        return (rs, rowNum)->{
            User user = new User("", "");
            user.setId(rs.getString("id"));
            user.setPw(rs.getString("pw"));
            return user;
        };
    }
  • DB에서 조회한 값을 객체로 감싸주는 메소드이다. 람다 형태로 작성한다.
  • 람다의 rs는 db의 레코드, rowNum은 레코드의 번호를 의미한다.
  • rs.getString("필드명"), rs.getInt("필드명") 등등의 메소드를 활용하여, 데이터를 매핑할 객체를 생성후 반환한다.
public Optional<User> findById(String id) {
        String query = "SELECT * FROM USER WHERE id=?;";
        List<User> result = jdbcTemplate.query(query, userRowMapper(), id);
        return result.stream().findAny();
    }
  • 이후 JdbcTemplate.query() 메소드에 위에서 정의한 쿼리 문자열과, RowMapper, 파라미터를 넘겨주면 된다.

데이터 삽입 후 자동 생성된 ID 반환(KeyHolder)

DB에서 Insert할때 id를 따로 넘겨주지 않아도, 자동으로 생성되도록 테이블을 만든 경우도 자주 볼 수 있다.
문제는 이렇게 생성된 id 및 레코드를 어떻게 조회할 것인가이다.

다행히 Jdbc Template에서는 PreparedStateKeyHolder을 사용하여, 레코드를 삽입한 후 자동 생성된 ID를 반환받을 수 있다.

아래는 사용 예제이다.

public Watch addWatch(Watch watch) {
        String query = "insert into watch (user_id, model, case_size, movement, lug_to_lug, glass) values (?, ?, ?, ?, ?, ?);";
        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(Connection con -> {
            PreparedStatement psmt = con.prepareStatement(query, new String[]{"id"});
            psmt.setString(1, watch.getUserId());
            psmt.setString(2, watch.getModel());
            psmt.setInt(3, watch.getCaseSize());
            psmt.setString(4, watch.getMovement());
            psmt.setInt(5, watch.getLugToLug());
            psmt.setString(6, watch.getGlass());
            return psmt;
        }, keyHolder);
        watch.setId(keyHolder.getKey().intValue());
        return watch;
    }
  • 자동생성된 키 값을 저장할 KeyHolder변수를 생성한다.

  • JdbcTemplate.update() 메소드에 PreparedStatementCreatorKeyHolder 변수를 넣어준다.

    • PreparedStatement는 함수형 인터페이스이다. 즉 이를 구현하는 람다 형태로 넘겨준다.관련문서

      • PreparedStatement 변수를 만들어 준다. PrepatedStatement는 SQL 문장을 컴파일? 해주는 변수이다.
        • Connection 변수의 preparedStatement()메소드를 사용하여 생성한다.
          • Connection변수는 DB와의 연결 객체이다.
          • 해당 메소드의 매개변수로 쿼리 문자열과, 리턴 받을 필드를 배열 형태로 넘긴다.
        • PreparedStatement변수의 setString(파라미터 순서, 파라미터 값), setInt(파라미터 순서, 파라미터 값) 등의 메소드를 사용하여 파라미터 값을 입력한다.
  • update() 문장 실행 후, KeyHolder가 가지고 있는 값을 getKey() 메소드를 사용하여 반환받는다.

profile
자바 BE 개발자 지망생입니다.

0개의 댓글