SpringBoot

[springBoot] 프로필 페이지 -양방향 매핑(mappedBy)

유쾌한고등어 2023. 1. 9. 16:29

프로필 페이지 -양방향 매핑(mappedBy)

 


1. model에 Image 추가

- 이미지,유저를 받아서 return 페이지에 보여주기위해 model.addAttribute

// UserController.java
...
@GetMapping("/user/{id}")
public String profile(@PathVariable int id,Model model){
    model.addAttribute("images",null);
    return "user/profile";
}

 

2. userService에 회원프로필() 생성

- 해당 Id를 가진 유저를 찾지못했을때 exception발동

// UserService.java

public class UserService {
	...
    public User 회원프로필(int userId){
        // SELECT * FROM IMAGE WHERE userId = :userId;
        User userEntity = userRepository.findById(userId).orElseThrow(()->{
            throw new CustomException("해당 프로필 페이지는 없는 페이지 입니다.");
        });
        return userEntity;
    }

 

3. 예외처리를 위한 CustomException.java 만들기

// CustomException.java
public class CustomException extends RuntimeException{
    private static final long serialVersionUID = 1L;
    public CustomException(String message){
        super(message);
    }
}

 

4. ExceptionHandler에 해당 예외처리 추가

// ControllerExceptionHandler.java
...
	@ExceptionHandler(CustomException.class)
    public String Exception(CustomException e){
        return Script.back(e.getMessage());
    }
...

 

5. 유저컨트롤러에 유저서비스 DI 및 model에 유저넣기

    // UserController.java
    
    private final UserService userService;
    ...
    @GetMapping("/user/{id}")
    public String profile(@PathVariable int id,Model model){
        User userEntity = userService.회원프로필(id);
        model.addAttribute("images",userEntity);
        return "user/profile";
    }
    ...

- 회원프로필페이지에는 유저정보 + 이미지정보 + 게시글정보등등...여러 데이터 정보들을 가지고 가야한다.
- ex)  1번유저정보 select->영속성컨텍스트에없음->DB에서 들고옴->영속성컨텍스트에 들어옴(영속화). but,User에는 Image정보가 없음. 따라서 User를 select할때 유저관련이미지를 같이 뽑아오는 로직을 만들것임.이를 위한 개념이 "양방향 맵핑"

 

- 이미지 select->유저정보를 들고온다.

- 유저 select->유저정보만들고오고 이미지는 들고오지않는다.

 

5. 양방향 맵핑

- 관계설정: 한 User는 여러개의 Image를 갖는다. ( @OneToMany )

- mappedBy user: 나는 연관관계의 주인이아니다.그러므로 테이블에 Column을 만들지말라는 뜻.

(연관관계의 주인은 Image Table의 user다)


- fetchType.Eager:

   *User를 Select할때 해당 User id(User-id)로 등록된 image(Image-user 1)들을 Join해서 다 가져오라는명령
   *@oneTomany는 fetchtype이 lazy default


- fetchType.Lazy:

  *User를 Select할때 해당 User id로 등록된 image들을 가져오지말라는 뜻이다.

  *대신 getImages()의 image들이 호출될때 image데이터를 가져온다.

  *user를 select한다고 무조건 가져오지않고, getImages의 image들이 호출될때 select을 해서 가져온다.

  *ex_ UserEntity.getImages().get(0) 

 

// User.java
...
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY) 
private List<Image> images;
...

 

 

- fetch type Lazy 예시

// UserService.java
    ...
    public User 회원프로필(int userId){
        User userEntity = userRepository.findById(userId).orElseThrow(()->{
        // 이미지를 같이 들고오지않음.
        
        UserEntity.getImages.get(0); //이때 Join이 일어난다.
    }

 

 


*정리*
user프로필페이지로 갈때 유저정보와 이미지 같이 가져가려면 양방향 맵핑을 하면 해결된다.