쪽지 조회의 문제점은 아래와 같았다.
- 내가 보낸 쪽지 조회와 받은 쪽지 조회의 코드가 너무나도 유사하다. 개발자or기업의 이름때문에 저렇게 중복되는 코드를 작성해야하는걸까?
List<Message> messageList = messageRepository.findAllByReceiverId(receiveId);
List<MessageSendResponse> messageSendResponses = new ArrayList<>();
for (Message message : messageList) {
if(receiveId.startsWith("C")){
Programmer programmer = programmerRepository.findById(message.getSenderId())
.orElseThrow(() -> new NoSuchElementException(message.getSenderId() + "님이 보낸 쪽지가 없습니다."));
messageSendResponses.add(new MessageSendResponse(message.getId(), programmer.getName()));
}
if(receiveId.startsWith("P")){
Company company = companyRepository.findById(message.getSenderId())
.orElseThrow(() -> new NoSuchElementException(message.getSenderId() + "님이 보낸 쪽지가 없습니다."));
messageSendResponses.add(new MessageSendResponse(message.getId(), company.getCompanyname()));
}
}
return messageSendResponses;
}
근데 약간 굳이인 것 같다는 생각이 들었다.
첫번째로 생각한건
message 엔티티에 senderName을 추가해서 쪽지를 생성할 때 senderName을 같이 줘서 조회할 때 가져오는 방식을 사용했다.
public MessageResponse create(String senderId, MessageRequest request) {
String receiverName = "";
if(request.receiverId().startsWith("C")){
Company company = companyRepository.findById(request.receiverId())
.orElseThrow(() -> new NoSuchElementException("해당 기업이 존재하지 않습니다!"));
receiverName = company.getCompanyname();
}
if (request.receiverId().startsWith("P")) {
Programmer programmer = programmerRepository.findById(request.receiverId())
.orElseThrow(() -> new NoSuchElementException("해당 개발자가 존재하지 않습니다!"));
receiverName = programmer.getName();
}
Message message = messageRepository.save(
new Message(
senderId,
request.receiverId(),
receiverName
));
return new MessageResponse(
message.getId(),
message.getReceiverId(),
receiverName;
}
public List<MessageSendResponse> findAllSendMessages(String senderId) {
List<Message> messageList = messageRepository.findAllBySenderId(senderId);
List<MessageSendResponse> messageSendResponses = new ArrayList<>();
for (Message message : messageList) {
messageSendResponses.add(new MessageSendResponse(message.getId(), message.getSenderName()));
}
return messageSendResponses;
}
이렇게 메세지의 id와 보낸 사람의 이름만 저장을 해 조회할 때도 이름만 보이게 된다.
public List<MessageSendResponse> findAllSendMessages(String receiverId) {
List<Message> messageList = messageRepository.findAllBySenderId(senderId);
List<MessageSendResponse> messageSendResponses = new ArrayList<>();
for (Message message : messageList) {
messageSendResponses.add(new MessageSendResponse(message.getId(), message.getSenderName()));
}
return messageSendResponses;
}
받은 쪽지도 보낸 사람의 이름이 포함되어야하는 거니까 senderName이 있는건 똑같은 것이다.
근데 문제점이 있다.
❗️따지고 보면 receiverName이 있어야 하고, senderName도 있어야한다.
❓근데 둘 다 칼럼에 저장하는 것이 맞는가?
이미 sender or receiver id가 있는데 굳이인 거 아닐까? id를 통해서 알 수 있지 않을까?
그럼 id를 통해서 그 이름을 알아보자
쿼리메서드로 할 수 있지 않을까?
String findReceiverNameByReceiverId(String receiverId);
String findSenderNameBySenderId( String senderId);
이런 코드를 작성해봤다. senderId를 통한 senderName을 찾는 쿼리 메서드이다.
근데 애초에 String 값으로 return타입을 적는 것도 안된다 했기 때문에 이거 실행하면 에러난다. 그리고 이게 성립될 수 없는 이유는
senderId와 실제 sender는 join(ManyToOne)이 되어 있지 않기 때문에 join을 할 수가 없다!!!!!!!
따라서 다른 코드를 작성해야한다.
그럼 Id를 찾아서 그 Id에 대한 아이를 먼저 찾은 다음에 그 속에 name을 적으면 되지 않을까?
나는 그래서 getSenderName / getReceiverName 함수를 따로 만들었다. 그래서 만약에 보낸사람 혹은 받은 사람이 C/P인지 구별하고, 그 이후 해당 Name을 가져오는 방법으로 하면 구현했다.
// 보낸 사람의 이름 가져오기 (받은 쪽지함에서 사용)
private String getSenderName(String senderId) {
if(senderId.startsWith("C")){
Company company = companyRepository.findById(senderId).orElseThrow();
return company.getCompanyname();
} else if (senderId.startsWith("P")) {
Programmer programmer = programmerRepository.findById(senderId).orElseThrow();
return programmer.getName();
}
throw new IllegalArgumentException("에러");
}
전체 코드는 그래서 전체 조회할 때 get~Name을 가지고 구현하게 되었다.
//보낸 쪽지함(내가 보낸 메세지)
public List<MessageResponse> findAllSendMessages(String senderId) {
List<Message> messageList = messageRepository.findAllBySenderId(senderId)
.stream()
.filter(message -> !message.isDeletedBySender()) // 내가 삭제한 메세지 빼고
.toList();
return messageList.stream()
.map(message -> new MessageResponse(
message.getId(),
message.getReceiverId(),
message.getSenderId(),
getReceiverName(message.getReceiverId()) // 받는 사람 이름 조회
))
.toList();
}
// 받는 사람의 이름 가져오기 (보낸 쪽지함에서 사용)
private String getReceiverName(String receiverId) {
if(receiverId.startsWith("C")){
Company company = companyRepository.findById(receiverId).orElseThrow();
return company.getCompanyname();
} else if (receiverId.startsWith("P")) {
Programmer programmer = programmerRepository.findById(receiverId).orElseThrow();
return programmer.getName();
}
throw new IllegalArgumentException("에러 ");
}