MyBatis DB연결 세팅 (2) : DTO로 req, resp 응답하기

bethe·2022년 9월 2일
0

Springboot

목록 보기
28/46
post-custom-banner

3. Reponse DTO로 return 값 받기

클라이언트에게 Insert가 잘 되었다고 알려주기 위해서는 통신을 통일해야 함. Response DTO를 만듬

Reponse DTO코드

package site.metacoding.red.web.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

//@Data<-getter setter toString이 있는데 헷갈려지니 겟터셋터를 쓰자
@AllArgsConstructor
@Setter
@Getter
public class RespDto<T> {
	private Integer code; //1정상, -1실패
	private String msg; // 통신에 대한 결과 메시지 담기
	private T body; // body가 메서드마다 다르므로 제네릭 사용 
}
package site.metacoding.red.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import site.metacoding.red.domain.users.Users;
import site.metacoding.red.domain.users.UsersDao;
import site.metacoding.red.web.dto.RespDto;

@RequiredArgsConstructor
@RestController
public class UsersController {

	private final UsersDao usersDao;
	
	@GetMapping("/users/{id}")
	public RespDto<?> getUsers(@PathVariable Integer id) {
		return new RespDto<>(1, "성공", usersDao.findById(id));
				//new 할 때 제네릭에 <> 값을 생략해도 됨
	}
	
	@GetMapping("/users")
	public RespDto<?> getUserList(){
		return new RespDto<>(1, "성공", usersDao.findAll());
	}
	
	@PostMapping("/users")
	public RespDto<?> insert(Users users) {
		usersDao.insert(users);
		return new RespDto<>(1, "회원가입완료", null);
	}
}
public interface UsersDao {
	public void insert(Users users);
	public Users findById(Integer id);
	public List<Users> findAll();
}

Integer 1을 return하지 않고 insert(삽입)만 하므로 void

Insert를 정확히 하는 법

Insert를 받을 때는 정확히 username, password, email을 받으므로

	@PostMapping("/users/{id}")
	public RespDto<?> insert(@PathVariable Integer id, Users users) {
		usersDao.insert(users);
		return new RespDto<>(1, "회원가입완료", null);
	}

가령 주소 뒤에 id를 붙일 경우 @PathVariable에서 Users users에도 id가 들어감으로써 헷갈리는 일이 발생한다. (이중매핑)

Tip : @RequestBody로 json으로 받을 경우 주소 값은 받지 않고 body값만 받아서 괜찮다

세분화해서 DTO를 만드는 이유 적기
(이름 이렇게 적는 이유도 적기)

package site.metacoding.red.web.dto.reqest.users;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class JoinDto {
	private String username;
	private String password;
	private String email;
}

Controller

	@PostMapping("/users")
	public RespDto<?> insert(JoinDto joinDto) {
		usersDao.insert(joinDto);
		return new RespDto<>(1, "회원가입완료", null);
	}

Dao 변경

import java.util.List;

import site.metacoding.red.web.dto.reqest.users.JoinDto;

public interface UsersDao {
	public void insert(JoinDto joinDto);
	public Users findById(Integer id);
	public List<Users> findAll();
}

=>

	<insert id="insert">
		INSERT INTO users(id, username, password, email, createdAt) 
		VALUES(users_seq.nextval, #{username}, #{password}, #{email}, sysdate)
	</insert>

정확하게 매칭되는 것


email값이 empty로 넘어옴

이렇게 하면 세 가지 말고는 안받겠다는 것
아이디가 null값도 안 되고 날짜도 null값도 안되잖아
사용자가 보닐 때 유효성 검사를 해야 함

4. update -1

  1. DAO 만들기
public interface UsersDao {
	public void insert(JoinDto joinDto);
	public Users findById(Integer id);
	public List<Users> findAll();
	public void update(Integer id, UpdateDto updateDto);
}

담을 내용이 JoinDto라서 JoinOrUpdateDto로 한번에 써도 되지만 일단은 연습용으로 Update Dto를 만들어서 사용했다.
(회사다마다의 컨벤션-규칙)에 따라서 알아서 잘 판단해서 만들자

  1. DTO 만들기
package site.metacoding.red.web.dto.reqest.users;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class UpdateDto {
	private String username;
	private String password;
	private String email;
}
  1. Mabits문법 쿼리문
	<update id="update">
		UPDATE users
		SET username = #{username},
		password = #{password},
		email = #{email}
		WEHRE id = #{id}
	</update>

순서가 다르게 넘어오는 파라매터를 제대로 mapping할까?

4.Controller

	@PutMapping("users/{id}")
	public RespDto<?> update(@PathVariable Integer id, UpdateDto updateDto){
		usersDao.update(id, updateDto);
		return new RespDto<>(1,"회원수정완료",null);
	}


터짐.. 왜냐면 두 개의 바인딩 못합니다 (id의 경우 주소창의 id와 updateDto의 null값이 두 개가 충돌하겠지)
진짜못할까? 문법으로.. 바인딩 할 수 있는 방법이 있어요! 하지만 그러면 코드가 지저분해지니까...

하나로 받는 방법으로 해보자!

update 4 -2

주소에는 통신을 위한 DTO로 값을 받고 (반드시 통신을 위한 DTO로 받아야 함 Users로 바로 받으며 안 됨) : 안그럼 null값이 들어오고 유효성 검사하기 힘들어짐
메서드 안에서 DB와 통신할 DTO(Users)로 값을 변환해 return한다

	@PutMapping("users/{id}")
	public RespDto<?> update(@PathVariable Integer id, UpdateDto updateDto){
		usersDao.update(id, updateDto);
		return new RespDto<>(1,"회원수정완료",null);
	}

에서
usersDao.update(id, updateDto); updateDto를 user object로 변환하면서 id를 집어넣으면 됨

	@PutMapping("users/{id}")
	public RespDto<?> update(@PathVariable Integer id, UpdateDto updateDto){
		Users users = new Users();
		users.setId(id);
		users.setUsername(updateDto.getUsername());
		users.setPassword(updateDto.getPassword());
		users.setEmail(updateDto.getEmail());
		usersDao.update(users);
		return new RespDto<>(1,"회원수정완료",null);
	}

DAo도 수정

public interface UsersDao {
	public void insert(JoinDto joinDto);
	public Users findById(Integer id);
	public List<Users> findAll();
	public void update(Users users);
}

5. Delete

Dao

public interface UsersDao {
	public void insert(JoinDto joinDto);
	public Users findById(Integer id);
	public List<Users> findAll();
	public void update(Users users);
	public void delete(Integer id);
}

Controller

@DeleteMapping("/users/{id}")
	public RespDto<?> delete(@PathVariable Integer id){
		usersDao.delete(id);
		return new RespDto<>(1,"회원삭제완료",null);
	}

Mybatis xml파일

	<delete id="delete">
		DELETE FROM users WHERE id = #{id}
	</delete>

profile
코딩을 배우고 기록합니다. 읽는 사람이 이해하기 쉽게 쓰려고 합니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 12월 3일

감사합니다.

답글 달기