- JDBC는 Java Database Connectivity로 DB에 접근할 수 있도록 Java에서 제공하는 API이다.
- JDBC에 연결해야하는 DB의 JDBC 드라이버를 제공하면 DB 연결 로직을 변경할 필요없이 DB 변경이 가능하다.
- DB 회사들은 자신들의 DB에 맞도록 JDBC 인터페이스를 구현한 후 라이브러리로 제공하는데 이를 JDBC 드라이버라 부른다.
- 서버를 변경할때 드라이버만 교체하면 손쉽게 DB 변경이 가능하지만, DB에 연결하기 위해서는 아직 여러가지 작업이 필요하다.
- 이러한 불편함을 해결하기 위해 커넥션 연결, statement 준비 및 실행, 커넥션 종료 등의 반복적이고 중복되는 작업들을 대신 처리해주는 JdbcTemplate이 등장했다.
- application.properties에 DB에 접근하기 위한 정보를 작성한다.
spring.datasource.url=jdbc:mysql://localhost:3306/memo spring.datasource.username=root spring.datasource.password={비밀번호} spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
- build.gradle에 JDBC 라이브러리와 MySQL을 등록한다.
implementation 'mysql:mysql-connector-java:8.0.28' implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
- DB연결이 필요한 곳에서 JdbcTemplate을 주입받아와 사용한다.
private final JdbcTemplate jdbctemplate; public memoRepository(JdbcTemplate jdbctemplate) { this.jdbctemplate = jdbctemplate; }
- 생성자의 파라미터를 통해 JdbcTemplate 객체가 자동으로 넘어와 jdbctemplate 변수에 저장된다.
String sql = "INSERT INTO memo (username, contents) VALUES (?, ?)"; jdbcTemplate.update(sql, "KIM_TABLE_NEXT", "오늘 하루도 화이팅!");
- INSERT SQL을 작성해 String 변수에 저장한 후
update()
메서드 첫 번째 파라미터에 넣어준다.
- 이때, 넣고자 하는 데이터 부분에
?
를 사용하면 유동적으로 데이터를 넣어줄 수 있다.jdbcTemplate.update()
메서드는 INSERT, UPDATE, DELETE 와 같이 생성, 수정, 삭제에 사용될 수 있는데 첫 번째 파라미터로 SQL을 받고 그 이후에는 ?에 들어갈 값을 받는다.
String sql = "UPDATE memo SET username = ? WHERE id = ?"; jdbcTemplate.update(sql, "KIM_TABLE_NEXT", 1);
- UPDATE SQL을 작성해 String 변수에 저장한 후
update()
메서드 첫 번째 파라미터에 넣어준다.
String sql = "DELETE FROM memo WHERE id = ?"; jdbcTemplate.update(sql, 1);
- DELETE SQL을 작성해 String 변수에 저장한 후
update()
메서드 첫 번째 파라미터에 넣어준다.
String sql = "SELECT * FROM memo"; return jdbcTemplate.query(sql, new RowMapper<MemoResponseDto>() { @Override public MemoResponseDto mapRow(ResultSet rs, int rowNum) throws SQLException { // SQL 의 결과로 받아온 Memo 데이터들을 MemoResponseDto 타입으로 변환해줄 메서드 Long id = rs.getLong("id"); String username = rs.getString("username"); String contents = rs.getString("contents"); return new MemoResponseDto(id, username, contents); } });
- SELECT SQL을 작성해 String 변수에 저장한 후
query()
메서드 첫 번째 파라미터에 넣어준다.- SELECT의 경우 결과가 여러 줄로 넘어오기 때문에
RowMapper
를 사용하여 한 줄씩 처리 할 수 있다.
RowMapper
는 인터페이스 이기 때문에 익명 클래스를 구현하여 처리한다.- 오버라이딩 된
mapRow
메서드는 제네릭스에 선언한 MemoResponseDto 타입으로 데이터 한 줄을 변환하는 작업을 수행한다.
- 전에 진행한 일정관리 프로젝트는 Controller 클래스 하나로 모든 API를 처리하고 있다.
- 현재는 API 수가 적고 기능이 단순하여 코드가 복잡해 보이지 않을 수 있지만 앞으로 기능이 추가되고 복잡해진다면 문제가 발생할 수 있다.
- 한 개의 클래스에 너무 많은 양의 코드가 존재하기 때문에 코드를 이해하기 어렵다.
- 현업에서는 코드의 추가 혹은 변경 요청이 계속 생길 수 있다.
- 문제가 발생했는데 해당 Controller 클래스를 구현한 개발자가 퇴사한다면?
이러한 문제점들을 해결하기 위해 서버 개발자들은 서버에서의 처리과정이 대부분 비슷하다는 걸 깨닫고, 처리 과정을 크게
Controller
,Service
,Repository
3개로 분리했다.
- 클라이언트의 요청을 받는다.
- 요청에 대한 로직 처리는
Service
에게 전담한다.
Request 데이터
가 있다면Service
에 같이 전달한다.Service
에서 처리 완료된 결과를 클라이언트에게 응답한다.
- 사용자의 요구사항을 처리 ('비즈니스 로직') 하는 실세 중에 실세다.
- 따라서 현업에서는 서비스 코드가 계속 비대해지고 있다.
- DB 저장 및 조회가 필요할 때는
Repository
에게 요청한다.
- DB 관리 (연결, 해제, 자원 관리) 한다.
- DB CRUD 작업을 처리한다.
강의를 더 듣고나니 더욱더 저번 일정관리 프로젝트를 잘못 설계했다는 생각이 들었다.
오늘 공부했던 내용과, 앞으로 배울 내용을 종합하여 다음 프로젝트부터는 더욱 예쁘게 설계해봐야겠다.
생각보다 Spring이 많은 기능을 도와주는것 같다.