https://maeilcoding.tistory.com/115
Controller, DAO, DTO 알아보기 // 예제 - 유저관리 API POST
DAO (Data Access Object) 란?데이터베이스나 기타 영속성 메커니즘에 접근하는 객체 목적: 데이터 접근 로직과 비즈니스 로직을 분리기능: CRUD(Create, Read, Update, Delete) 작업 수행사용이유: - 코
maeilcoding.tistory.com
저번 글에서 작성한 Post 리퀘스트가 성공적으로 response 되는지 확인해봅시다.
유저 이름과 이메일을 관리하는 API만들기 예제 // todo 2 getUserById
1. 명세서 확인
2. Postman에 리퀘스트 작성
* POST, PUT, 그리고 PATCH 메서드는 Request Body를 통해 데이터를 전송하지만, GET, DELETE 등 대부분의 다른 메서드는 보낼 데이터가 없어 Request Body를 사용하지 않는 것이 일반적이다.
2. Controller에서 getUserInfoById 메서드 작성 시작
//todo 2 getUserInfoByid
@GetMapping("/api/users/{id}")
getUserInfoByid(@PathVariable long id){
@GetMapping("/path")
URL경로에 포함된 id값을 메서드 파라미터로 바인딩
@PathVariable long id
URL경로에서 추출한 id값을 id 변수에 바인딩
DB작업은 어디서? DAO에서 할거니까 다시 DAO로 이동
3. DAO 에서 get 메서드 만들기
//todo Get id
get UserInfoById(long id){
String sql = "SELECT *\n" +
"FROM user\n" +
"Where id=?;";
return jdbcTemplate.queryForObject(sql, );
jdbcTemplate.queryForObject (sql, 클래스 구현체, 파라미터 값)
SQL 쿼리를 실행하고 결과를 ResultSet 객체로 매핑
sql = SQL문 쿼리 "SELECT * FROM user WHER id=?;"
클래스 구현체 = RowMapper = 쿼리 결과 반환된 ResultSet을 특정 객체에 변환하는데 쓰임
파라미터 값 = id (SQL의 ?가 바인딩)
4. RowMapper 처리 클래스 작성
RowMapper(Spring JDBC에서 제공한 인터페이스, DB 결과 행-ResultSet을 자바 객체로 매핑)를 처리해 줄 클래스를 만듭니다.
이 클래스는 외부 클래스들의 인스턴스가 필요없기 때문에 static으로 만듭니다.
RowMapper 인터페이스를 implemnets 받았기 때문에 오버라이딩 필요
오버라이딩하면 메서드를 작성할 수 있다.
private static class UserRowMapper implements RowMapper<User>{
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return null;
}
}
RowMapper<User>
<> 제네릭: 데이터 타입을 일반화한다. 객체 타입 안정성을 높임, 반환값에 대한 타입 변환, 검사에 들어가는 노력을 줄일 수 있음.
Spring JDBC에서 제공하는 인터페이스 쿼리 결과를 User 객체로 매핑
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user =new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
user.getCreatedAt(rs.getLong("created_at");
return user;
}
ResultSet rs = sql 쿼리 결과의 각 행(Row)을 나타냄
각 컬럼의 값을 가져와 User 객체의 필드에 설정
>> 최종적으로 User 객체가 변환되어 반환됨
예행 시나리오
1. 클라이언트가 '/api/users/1'요청 > DAO 메서드 호출
User user = getUserInfoById(1);
2. sql 실행 결과
SELECT * FROM user WHERE id =1;
3. ResultSet을 User로 매핑
User user = new User();
user.setId(1);
user.setName("김나나");
user.setEmail("nana@mail.com")
user.setCreatedAt("2024-12-22 17:33:00")
4. User 객체 반환
User{id=1, name="김나나", email="nana@mail.com", createdAt"2024-12-22 17:33:00"}
6. DAO 에서 get 메서드 마저 만들기
//todo Get id
getUserInfoById(long id){
String sql = "SELECT *\n" +
"FROM user\n" +
"Where id=?;";
return jdbcTemplate.queryForObject(sql, 클래스 구현체, 파라미터 값));
클래스 구현체인 UserRowMapper를 만들었으니 qureyForObject의 파라미터를 작성합니다.
getUserInfoById()의 메서드 반환타입인 User 작성
//todo Get id
public User getUserInfoById(long id){
String sql = "SELECT *\n" +
"FROM user\n" +
"Where id=?;";
return jdbcTemplate.queryForObject(sql, new UserRowMapper(), id);
}
private static class UserRowMapper implements RowMapper<User>{
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user =new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
user.getCreatedAt(rs.getLong("created_at");
return user;
}
}
DAO의 메서드 완성했으니
Controller 메서드도 마저 완성
7. 명세서 요구사항에 이번엔 status, data를 필요로 한다. DTO를 하나 더 만들자
dto/UserOneResDTO 생성
data는 유저 객체를 담아올 거니까 User data;
public class UserOneResDTO {
public String status;
public User data;
public UserOneResDTO() {
}
public UserOneResDTO(String status, User data) {
this.status = status;
this.data = data;
}
}
8. Controller 메서드 마저 완성
//todo 2 getUserInfoByid
@GetMapping("/api/users/{id}")
ResponseEntity<UserOneResDTO> getUserInfoByid(@PathVariable long id) {
try {
User user = userDAO.getUserInfoById(id);
return ResponseEntity.status(200).body(new UserOneResDTO("success", user));
} catch (Exception e) {
return ResponseEntity.status(400).build();
}
}