Loading...

Spring/Blog-V2 / / 2022. 3. 25. 22:06

스프링 50강. throw

반응형


======= 회원정보 수정하기 =======

회원 정보 페이지를 달라고 요청하는 거니까

주소에 /api를 붙이지 않는다.


좀 특이한 건 그냥 페이지 요청이 아니라

데이터를 넣어서 페이지 달라고 요청한다.

제일 쉬운 방법은 DB에서 id로 SELECT 해서 모델에 담으면 되는데
앱까지 같은 서버로 제공한다면 fetch를 사용해야 한다.

공통적으로!!

원래는 findById( ) 메서드를 요청하면 Optional<User> 타입을 리턴해줘서

isPresent( )로 안에 값이 있으면 return userOp.get( ) 하고,

값이 없으면 null을 리턴하는데
null이 리턴되면 결국 머스태치에서 터지게 된다.

뷰 랜더링 할 때!


null을 리턴하는 것은 위험하다.


내가 직접 강제로 Exception을 터뜨려줘야 한다.

 

throw new RuntimeException("아이디를 찾을 수 없습니다.");


강제로 Exception을 터뜨리는 것을 throw라고 한다.

강제로 터진 이 Exception을 에러 핸들러가 낚아챌 것이다.

내가 메세지도 넣어줄 수 있다.

 

@Transactional
public User 회원수정(Integer id, UpdateDto updateDto) {
    // UPDATE user SET password = ?, email = ?, address = ? WHERE id = ?
    Optional<User> userOp = userRepository.findById(id); // 영속화 (DB의 row를 영속성 컨텍스트에 옮김)

    if (userOp.isPresent()) {
        // 영속화된 오브젝트 수정
        User userEntity = userOp.get();

        userEntity.setPassword(updateDto.getPassword());
        userEntity.setEmail(updateDto.getEmail());
        userEntity.setAddress(updateDto.getAddress());

        return userEntity;
    } else {
        throw new RuntimeException("회원수정에 실패하였습니다.");
    }

} // 트랜잭션이 걸려있으면 @Service가 종료될 때 변경 감지 후 DB에 UPDATE -> 더티체킹

 

package site.metacoding.blogv2.web.api.dto.user;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class UpdateDto {
    private String password;
    private String email;
    private String address;
}

 

// 유저정보 수정 password, email, address
@PutMapping("/s/api/user/{id}")
public ResponseDto<?> update(@PathVariable Integer id, @RequestBody UpdateDto updateDto, Model model) {

    // System.out.println("id : " + id + ", updateDto : " + updateDto);

    User userEntity = userService.회원수정(id, updateDto);

    return new ResponseDto<>(1, "업데이트 성공", null);
}

 

{{> /layout/header}}

<!-- 컨테이너 시작 -->
<div class="container mt-3">

  <!-- 회원수정 폼 시작 -->
  <form>
    <input id="id" type="hidden" value="{{user.id}}">

    <div class="mb-3 mt-3">
      <input id="username" type="text" class="form-control" value="{{user.username}}" readonly>
      <!--username readonly-->
    </div>
    <div class="mb-3">
      <input id="password" type="password" class="form-control" value="{{user.password}}" maxlength="12" required>
    </div>
    <div class="mb-3">
      <input id="email" type="email" class="form-control" value="{{user.email}}" maxlength="30" required>
    </div>
    <div class="mb-3">
      <input id="address" type="text" class="form-control" value="{{user.address}}" maxlength="300" required>
    </div>

    <button id="btn-update" type="button" class="btn btn-primary">수정완료</button>
  </form>
  <!-- 회원수정 폼 끝 -->

</div>
<!-- 컨테이너 끝 -->

<script src="/js/user.js"></script>

{{> /layout/footer}}

 

$("#btn-update").click(() => {
    update();
});

// 회원정보 수정 함수
async function update() {
    let updateDto = {
        password: $("#password").val(),
        email: $("#email").val(),
        address: $("#address").val()
    }

    let id = $("#id").val();

    let response = await fetch(`/s/api/user/${id}`, {
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        },
        method: 'PUT',
        body: JSON.stringify(updateDto)
    });

    let responseParse = await response.json();

    // console.log(responseParse);

    if (responseParse.code == 1) {
        alert("수정이 완료되었습니다.");
        location.href = `/s/user/${id}`;
    } else {
        alert("수정에 실패했습니다.");
    }
}

 


 

UPDATE시에 영속화가 아닌 직접 네이티브 쿼리를 만들어서 사용해도 된다.

// UPDATE시에 영속화말고 직접 네이티브 쿼리를 짜도됨 
@Modifying // 네이티브쿼리로 WRITE 작업을 하려면 이 어노테이션을 붙여줘야함 = executeUpdate()
@Query(value="UPDATE user SET password = :password, email = :email, address= :address WHERE id=:id", nativeQuery = true)
void mUpdate(@Param("password") String password, @Param("email") String email, @Param("address") String address, @Param("id") Integer id);

 

네이티브 쿼리로 DB에 WRITE 요청을 할 때는

@Modifying 어노테이션을 붙여줘야 한다.

 

우리가 prepareStatement를 사용할 때와 같이

WRITE 요청에 @Modifying 어노테이션을 붙이는 것은 executeUpdate( )가 실행되는 것과 같고,

SELECT 하는 쿼리는 executeQuery( )가 실행되는 것과 같은 것이다.

 

 

 

 

 

 

 

[출처]

 

https://cafe.naver.com/metacoding

 

메타코딩 : 네이버 카페

코린이들의 궁금증

cafe.naver.com

메타 코딩 유튜브

https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9

 

메타코딩

문의사항 : getinthere@naver.com 인스타그램 : https://www.instagram.com/meta4pm 깃헙 : https://github.com/codingspecialist 유료강좌 : https://www.easyupclass.com

www.youtube.com

 
반응형