스프링 부트와 MySQL 연동에 관련된 글은 이전 포스팅을 참고하자
이번에는 연동한 DB를 스프링 부트 프로젝트 안에서 사용하는 방법을 정리하려고 한다.
스프링 부트에서 DB를 사용하는 방식은 아래와 같은 여러가지가 있다.
- JDBC
- JDBC Template
- JPA
- 등등
요즘에는 JPA가 가장 많이 쓰이는 것 같은데, 나는 우선 SQL 쿼리 짜는걸 연습할 겸 JDBC Template을 사용하였다. JDBC Template은 JDBC에 비해 복잡한 설정 코드를 작성하지 않아도 된다는 장점이 있다.
그럼 JDBC 사용 방법을 알아보자.
Repository 클래스 생성 및 의존관계 설정
- 우선 스프링 부트 프로젝트에서, DB와의 연결을 책임질 Repository 클래스를 만들어 준다.
- 의존 관계 설정
- Repository안에서 JDBC Template를 사용하기 위해
JdbcTemplate
멤버를 사용해야함JdbcTemplate
은DataSource
를 의존하기 때문에, 생성자에서 이에 대한 의존 관계를 주입해준다.
- Repository안에서 JDBC Template를 사용하기 위해
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;
}
- SQL 쿼리를 작성해준다. 여기서 매개변수로 넘길 값은
?
를 활용한 파라미터 형태로 작성한다. 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에서는 PreparedState
및 KeyHolder
을 사용하여, 레코드를 삽입한 후 자동 생성된 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()
메소드에PreparedStatementCreator
및KeyHolder
변수를 넣어준다.PreparedStatement는 함수형 인터페이스이다. 즉 이를 구현하는 람다 형태로 넘겨준다.관련문서
PreparedStatement
변수를 만들어 준다. PrepatedStatement는 SQL 문장을 컴파일? 해주는 변수이다.Connection
변수의preparedStatement()
메소드를 사용하여 생성한다.Connection
변수는 DB와의 연결 객체이다.- 해당 메소드의 매개변수로 쿼리 문자열과, 리턴 받을 필드를 배열 형태로 넘긴다.
PreparedStatement
변수의setString(파라미터 순서, 파라미터 값)
,setInt(파라미터 순서, 파라미터 값)
등의 메소드를 사용하여 파라미터 값을 입력한다.
update() 문장 실행 후,
KeyHolder
가 가지고 있는 값을getKey()
메소드를 사용하여 반환받는다.
'Back End > Spring && Spring Boot' 카테고리의 다른 글
[Spring Security] Spring Security 개념과 작동 방식 (0) | 2024.06.01 |
---|---|
[Spring boot] Ambiguous mapping. Cannot map '~' method 에러 (0) | 2024.06.01 |
스프링 부트 DB 연동(MySQL, JDBC Template) (0) | 2024.06.01 |
[Spring boot] URL로 파라미터 넘기기(@PathVariable, @RequestParam) (0) | 2024.06.01 |
Spring 웹 계층 구조, Spring Web Layer (0) | 2024.06.01 |