본문 바로가기
Spring/JPA + Security

[Spring Data JPA] 데이터 수정하기 + AJAX 포함 예제

by pyogowoon 2023. 1. 7.
<form id="profileUpdate" onsubmit="update(${principal.user.id} ,event)">

이런식으로 jsp 안에 버튼에 온클릭 이벤트 삽입(매개변수 id로 보냄)

 

그후 ajax처리

function update(userId,event) {
        event.preventDefault(); //폼 태그 액션 막기
       let data=$("#profileUpdate").serialize();

       console.log(data);

       $.ajax({

        type:"put",
        url:`/api/user/${userId}/`,
        data : data,
        contentType : "application/x-www-form-urlencoded; charset=utf-8",
        dataType: "json"

       }).done(res=>{
            alert("수정에 성공하였습니다.");
            location.href=`/user/${userId}`;
       }).fail(error=>{
            alert("수정에 실패하였습니다.");

       });

}

.serialize() 는 입력된 form 데이터의 element들을 모두 data로 한꺼번에 직렬화 할수있다

 아니면 serialize 안쓰고 직접 JSON으로 적어서

contentType 에 "application/JSON" 으로 보내도되고 선택은 자유

`` 백틱 사용하는 이유 : el식 쓰려고

새로 api 패키지 만들고 안에 api 컨트롤러 생성


@RequiredArgsConstructor
@RestController
public class UserApiController {


   private final UserService userService;
    //DATA를 응답하는 애들은 api

    @PutMapping("/api/user/{id}")
    public CMRespDto<?> update(UserUpdateDto userUpdateDto , @PathVariable int id) {

       User userEntity = userService.회원수정(id,userUpdateDto.toEntity());
        return new CMRespDto<>(1,"회원수정완료",userEntity);
    }

}

 

 

 

AJAX  통해서 보낸 URL을 통해 컨트롤러단에서 서비스로 보낸다 파라메터에는 새로만든Dto랑 세션값 id, session 넣고 이 과정에서 새로 UserUpdateDto를 만들었고 영속화 진행, 여기서

session값도 바로 수정해준다(바꾸고 난 후에 세션정보 남을수있도록).

 

DB와 통신하는 새로운 로직이 생겼으니, DTO도 만든다.

import com.pyo.yourspick.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 toEntity(){
            return User.builder()
                    .name(name)
                    .password(password)
                    .website(website)
                    .bio(bio)
                    .phone(phone)
                    .gender(gender)
                    .build();

    }

}
 

* 아직 널처리 낫널처리 안한상태이고

toEntity는 추후 @Entity 어노테이션으로 따로 지정 가능함. 빌더통해서 영속화 과정을 거쳐준다

 

service 패키지의 UserService 클래스로 가서

 


@RequiredArgsConstructor
@Service
public class UserService {

    private final UserRepository userRepository;

    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Transactional
    public User 회원수정(int id, User user) {
            //1. 영속화
        User userEntity = userRepository.findById(id).orElseThrow(()->
                new IllegalArgumentException("아이디 못찾음!"));


        //2. 영속화된 오브젝트를 수정 - 더티체킹(업데이트 완료
        userEntity.setName(user.getName());

        String rawPassword = user.getPassword();
        String encPassword = bCryptPasswordEncoder.encode(rawPassword);

        userEntity.setPassword(rawPassword);
        userEntity.setWebsite(user.getWebsite());
        userEntity.setWebsite(user.getWebsite());
        userEntity.setBio(user.getBio());
        userEntity.setPhone(user.getPhone());
        userEntity.setGender(user.getGender());
        return userEntity;
    } // 더티체킹이 되서 업데이트가 완료됨

}

 

Q . Repository.saveAll() 을 안써도 업데이트가 되나요? 된다면 어떻게 되는거?

 

A. @Transactional 어노테이션을 붙여주면 영속성 컨텍스트 에서의 변화를 감지하면 알아서 업데이트

하기 때문임

 

자, 이제 DB는 제대로 변경되었다 하지만 아직 세션에는 저장되지않았다, 저장해주자

 

@PutMapping("api/user/{id}")
    public CMRespDto<?> update(UserUpdateDto userUpdateDto, @PathVariable int id, @AuthenticationPrincipal PrincipalDetails principalDetails){


       User userEntity = userService.회원수정(id, userUpdateDto.toEntity());
        principalDetails.setUser(userEntity);
        return new CMRespDto<>(1, "업데이트 완료", userEntity);
    }
}

@AuthenticationPricipal 선언하고

 setUser에 userEntity를 넣어주자. 이제 세션을 넣었으면 

 

 

function update(userId) {


let data = $("#profileUpdate").serialize();

  $.ajax({
       type: "put",
       data: data,
       url: `/api/user/${userId}`,
       contentType: "application/x-www-form-urlencoded; charset=utf-8",
       dataType: "json"

  }).done(res => {
        console.log(res,"성공");
        location.href=`/user/${userId}`;

  }).fail(error => {
        console.log(error,"실패")


  })
}

이제 js에서 `` 백틱 사용해서 userId 받아서 되돌아가면 성공.

댓글