Wanna be Brilliant Full-Stack Developer

SpringBoot 회원정보수정 업데이트 완료 본문

Back-End/Spring Boot

SpringBoot 회원정보수정 업데이트 완료

Flashpacker 2022. 2. 12. 13:46


목표

DB에 업데이트를 진행하려고한다!  지난번에 코드 수정이 필요하다고 올린 부분을 수정하려고한다 (UserUpdateDto) 

package com.cos.photogramstart.web.dto.user;

import com.cos.photogramstart.domain.user.User;

import lombok.Data;

@Data
public class UserUpdateDto {
	private String name; //필수
	private String password; // 필수 
	private String website;
	private String bio;
	private String phone;
	private String gender;
	
	// 조금 위험함. 코드 수정이 필요할 예정
	public User toEntitiy() {
		return User.builder()
				.name(name)
				.password(password)
				.website(website)
				.bio(bio)
				.phone(phone)
				.gender(gender)
				.build();
	}
}

만약 패스워드를 기재 안했으면 공백으로 들어오면 데이터베이스에 공백의 패스워드가 들어오면 문제가된다.

그러면 Validation 체크를 해야한다 무조건 패스워드를 받아야하기때문!

name값을 받지 않아도 문제가 되기때문에 Validation 체크를 해야한다!

 

UserApiController에서 잘받았는데 id값도 받기 위해서 PathVariable int id;를 추가해 id를 받는다 

 

package com.cos.photogramstart.web.api;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cos.photogramstart.web.dto.user.UserUpdateDto;

@RestController
public class UserApiController {

	@PutMapping("/api/user/{id}")
	public String update(@PathVariable int id, UserUpdateDto userUpdateDto) {
		System.out.println(userUpdateDto);
		return "ok";
	}
	
}

이제는 실제로 수행할 서비스가 필요하다!

회원수정이 일어나기때문에  Write니까 @Transactional 어노테이션을 추가한다! 

package com.cos.photogramstart.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cos.photogramstart.domain.user.User;

@Service
public class UserService {

	@Transactional
	public User 회원수정(int id, User user ) {
		return null;
		
	}
}

 

또한 UserApiController에서 애가 서비스에 있는 회원수정을 호출해야 하니까 DI 의존성 주입을 해야한다!

package com.cos.photogramstart.web.api;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cos.photogramstart.domain.user.User;
import com.cos.photogramstart.service.UserService;
import com.cos.photogramstart.web.dto.CMRespDto;
import com.cos.photogramstart.web.dto.user.UserUpdateDto;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@RestController
public class UserApiController {

	private final UserService userService;
	
	@PutMapping("/api/user/{id}")
	public CMRespDto<?> update(@PathVariable int id, UserUpdateDto userUpdateDto) {
		User userEntity = userService.회원수정(id, userUpdateDto.toEntitiy());
		return new CMRespDto<>(1, "회원수정완료", userEntity);
	}
	
}

이상태에서 서비스를 완료하러간다 첫번쨰는 영속화를 해야한다, 2번쨰는 영속화된 오브젝트를 수정! 

수정이 완료되면 더티체킹을 통해 업데이트를 완료한다!

 

이를 위해서는 UserRepository가 필요하다. 

 또한 //.get을 붙인 이유는 findByid에서 내가 user 1번을 찾았는데 없으면 null이 리턴된다 자바에서는 래핑 클래스 Optional 를 만들어주는데 Optional은 머를 할수 있냐면

1. 무조건 찾았다 걱정마 get()

2. 못찾았어 익섹션 발통시킬게 orElseThrow() 

orElse라는 하나가 더 있지만 크게 중요하지 않아서 저위에 두개만 알면된다.

.get이라고 한이유는 익섹션 처리하는것을 나중으로 미루기 위해서이다. 

.get으로 찾아서 그 회원이 있는지 없는지 찾아서 userEntity에 담기게 되는것이 영속화인데!

 


여기서 영속화는 무엇인가? 

영속화 과정1

스프링부트 서버가 있고 데이터베이스에 User정보가 1번 정보가 있는데 FindById에서 1번정보를 찾았다. 

찾아서 들고오면 스프링부트 서버와 데이터베이스 사이에 영속성 컨텍스트 라는게 있는데

그 영속성 컨텍스트 안에 찾은 1번 객체가 쏙 들어간다 ( 이것이 영속화가 되었다는 것이다.) 

영속화된 데이터에는

id username password
1 ssar 1234

이렇게 들어가있을 것이다. 이 값들을 우리가 변경만 하면 변경된 정보가 DB에 반영이 된다. 그래서 영속화를 시킨것이다. 

1번 업데이트 할때는 해당 업데이트 하고 싶은 정보를 찾아서 영속화를 시키고 영속화된 오브젝트를 수정하면 자동으로 DB에 반영이 된다.!! 

영속화 완료

영속화를 완료하고나서 영속화된 오브젝트를 수정하게되면 수정된 오브젝트를 리턴을 또 해야한다! 

package com.cos.photogramstart.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cos.photogramstart.domain.user.User;
import com.cos.photogramstart.domain.user.UserRepository;

import lombok.RequiredArgsConstructor;


@RequiredArgsConstructor
@Service
public class UserService {

	private final UserRepository userRepository;
	
	@Transactional
	public User 회원수정(int id, User user ) {
		//1. 영속화
		User userEntity = userRepository.findById(id).get(); //1. 무조건 찾았다. 걱정마 get() 2. 못찾았어 익섹션 발통시킬때 orElseThrow()
	
		//2. 영속화된 오브젝트를 수정 - 수정이 완료되면 더티체킹 ( 업데이트 완료) 
		userEntity.setName(user.getName());
		userEntity.setPassword(user.getPassword());
		userEntity.setBio(user.getBio());
		userEntity.setWebsite(user.getWebsite());
		userEntity.setPhone(user.getPhone());
		userEntity.setGender(user.getGender());
		return userEntity;
		
	}//더티체킹이 일어나서 업데이트가 완료됨. 
}

과정 : 요청이 들어오면 회원수정을 유저 Api컨트롤러에서 하고 수정된 결과를 받아서 ajax로 호출한쪽으로 응답만 해줬다. 실제로 DB의 값이 변경되었는지 확인해야한다 

 

package com.cos.photogramstart.web.api;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cos.photogramstart.config.auth.PrincipalDetails;
import com.cos.photogramstart.domain.user.User;
import com.cos.photogramstart.service.UserService;
import com.cos.photogramstart.web.dto.CMRespDto;
import com.cos.photogramstart.web.dto.user.UserUpdateDto;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@RestController
public class UserApiController {

	private final UserService userService;
	
	@PutMapping("/api/user/{id}")
	public CMRespDto<?> update(@PathVariable int id, UserUpdateDto userUpdateDto, @AuthenticationPrincipal PrincipalDetails principalDetails) {
		User userEntity = userService.회원수정(id, userUpdateDto.toEntitiy());
		principalDetails.setUser(userEntity);
		return new CMRespDto<>(1, "회원수정완료", userEntity);
	}
	
}

다시 회원정보 변경을 클릭해도 정보가 그대로 반영이 되어있다.  왜냐하면 세션정보를 principalDetails.setUser(userEntity); 로 바꿔놨기때문이다.

 

이대로 끝나는것이아니라 update성공을 했으면 update.js 

location.href=`/user/${userId}`; 로 자기 원래페이지로 돌아가게한다! 

실패했으면 아무것도 안해도된다~

// (1) 회원정보 수정
function update(userId) {
	
	let data  =$("#profileUpdate").serialize();
	
	console.log(data);
	
	$.ajax({
		type: "put",
		url: `/api/user/${userId}`,
		data:data,
		conentType:"application/x-www-form-urlencoded; charset=utf-8",
		dataType:"json"
	}).done(res=>{
		console.log("update 성공");
		location.href=`/user/${userId}`;
	}).fail(error=>{
		console.log("update 실패");
	});
}

 

이곳에서 정보를 변경 업데이트를 완료하면? 
이곳으로 돌아온다!

다음에는 패스워드를 넣을떄도 있고 안넣을떄도 있으면 문제가 되니 이 문제를 처리하는것은 다음에 해보려고한다!