클라이언트에게 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를 받을 때는 정확히 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값도 안되잖아
사용자가 보닐 때 유효성 검사를 해야 함
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를 만들어서 사용했다.
(회사다마다의 컨벤션-규칙)에 따라서 알아서 잘 판단해서 만들자
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;
}
<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값이 두 개가 충돌하겠지)
진짜못할까? 문법으로.. 바인딩 할 수 있는 방법이 있어요! 하지만 그러면 코드가 지저분해지니까...
하나로 받는 방법으로 해보자!
주소에는 통신을 위한 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);
}
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>
감사합니다.