
App - 컨트롤러 DBDate - 엔티티(테이블) ViewData - DTO
ex01 - [ dbData1를 ViewData1에 옮기시오 - ORM ]
패키지




방법 1 - setter 사용 (제일 안 좋은 방법)

viewData1.setTitle(dbData.getTitle()); user.setTitle(dbData.getUserId()); 이런 식으로 ~
방법 2 - 생성자 사용 (@AllArgsConstructor)


방법 3 - 바뀌는 쪽(ViewData)에서 작업 (실무에서 사용) ✓
생성자를 직접 만들어야한다. lombok 사용하지 않고... 무조건 저 db 데이터를 가지고 화면을 만들거기 때문에 (우리가 만들 일 x) DBData1에게 직접 바로 받아오면 된다! 바뀌는 쪽에서 작업할 때, 생성자를 직접 만든다.

방법2처럼, 끄집어서 넣는 걸 ViewData1 클래스에서 해줌


방법 4 - 바꾸려고 하는 곳(DBdata)에서 작업
바꾸려고 하는 곳에서 (소스 코드에서) 바꾼다




from, of
메소드 이름이 from, of 라고만 되어있는 경우도 볼 수 있다.
from = DB 데이터로 부터 view 데이터를 만들 때
of(to) = 방법4

패턴인데… 아직도 몰라도 된다!
DTO가 많으면 코드가 더럽다
ex02 -[ dbList(컬렉션을) ViewData2(오브젝트)에 옮기시오 - ORM ]
게시글 1개당 댓글은 여러개일 수 있으니까, reply만 forEach문을 돌린다.
* App2를 컨트롤러라고 생각하자
* db쪽에서 주는 거 - viewData에서 파싱하는 거
방법 1 = 기본기 - 컨트롤러에서 파싱

if (dbList.size() == 0) return;
0이면 없다는 뜻이니까 return 때려서 종료시켜야함 -> nullPointException 뜰 수 있어서
(지금은 0 ~ 2번지만 있음)
dbList.get(0).getBoardId() > 0번지는 무조건 있을테니까 안전하게 0번지를 받아옴
1. for (DBData2 data : dbList) : dbList에 있는 각각의 DBData2 객체에 대해 반복
data는 현재 반복되고 있는 DBData2 객체를 나타낸다.
2. Reply r = new Reply(data.getReplyId(), data.getComment()) :
data 객체에서 댓글 ID와 댓글 내용을 가져와서 Reply 객체를 생성.
이때 data.getReplyId()는 DBData2 객체의 댓글 ID를 반환하고,
data.getComment()는 해당 댓글의 내용을 반환한다.
3. viewData2.addReply(r) : 앞서 생성한 Reply 객체 r을 viewData2에 추가.
addReply() 메서드는 ViewData2 클래스에 정의된 메서드로,
Reply 객체를 viewData2 내부의 댓글 목록에 추가하는 역할을 한다.

[ addReply ]
댓글을 추가하는 기능을 수행하는 메서드. 이 메서드는 ViewData2 클래스에 정의되어 있어서, ViewData2 객체에 새로운 댓글을 추가할 때 사용한다. (forEach문 도니까 그러거나... List로 받아서 그런듯...? 뭐가 되었건 스택이 닫혀도 저장되게 끔 하려고) 새로운 댓글을 매개변수로 받는다. 받은 댓글을 ViewData2 객체 내부에 있는 댓글 목록에 추가한다. 추가된 댓글을 ViewData2 객체 내부에서 유지하고 관리한다.
private List<Reply> replies = new ArrayList<>();
ViewData2 클래스에는 replies라는 이름의 List<Reply> 타입의 멤버 변수가 선언되어 있다
이 변수는 댓글들을 저장하고 관리하는 목적으로 사용된다.
초기 값으로는 빈 리스트(ArrayList)가 할당 됨.
public void addReply(Reply reply)
addReply() 메서드는 새로운 댓글을 replies 리스트에 추가하는 역할.
이 메서드는 Reply 객체를 매개변수로 받아서,
해당 댓글을 replies 리스트에 추가한다.
즉, replies.add(reply)를 호출하여 새로운 댓글을 리스트에 추가하는 동작을 수행.


기본기이나, 코드 재사용이 불가능함


방법 2 - Stream 1 (addReply 메소드 + forEach문 사용)


stack이 닫히면 new Reply 저게 사라지니까!! replies.add(reply) 해줌!

dbList.stream().forEach(data -> {
addReply(new Reply(data.getReplyId(), data.getComment()));
});
ViewData2 객체의 addReply 메소드를 호출하면서
새로운 Reply 객체를 매개변수로 전달하는 것
방법 3 - Stream 2 (addReply 메소드x, map으로 가공, toList로 수집)

data는 dbList의 각 요소를 가리키는 변수. dbList는 List<DBData2> 형식의 데이터이며, data는 이 리스트의 각 요소를 순회하면서 람다식으로 처리한다.
addReply 메소드 안 쓰는 방법
private List<Reply> replies = new ArrayList<>();
애가 .. 밑에 있어서 헷갈린다. 위로...
생성자가 new 뜬 다음에 생기니까 절차상으론 문제가 없는데 헷갈림 ㅠㅠ
방법 4 - forEach문

전체 코드
package ex02;
import ex02.model.Reply;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@NoArgsConstructor
@Data
public class ViewData2 {
private int boardId;
private String title;
private String content;
// Board 데이터만 넣는 생성자
public ViewData2(List<DBData2> dbList) {
if (dbList.size() > 0) { // 0일때 터짐 방지
this.boardId = dbList.get(0).getBoardId();
this.title = dbList.get(0).getTitle();
this.content = dbList.get(0).getContent();
}
// 첫번째 방법
//dbList.stream().forEach(data -> {
// addReply((new Reply(data.getReplyId(), data.getComment())));//});
// 두번째 방법
// map으로 가공해서 toList로 수집하면 data가 reply가 됨
// replies = dbList.stream().map(data->new Reply(data.getReplyId(), data.getComment())).toList();
// 세번째 방법
for(DBData2 data : dbList) {
Reply r = new Reply(data.getReplyId(), data.getComment());
addReply(r);
}
}
// 댓글들은 addReply로 추가하기 // 한건씩 만들어야하기 때문에 setter로 해결이 안되기 때문
private List<Reply> replies = new ArrayList<>();
public void addReply(Reply reply) {
replies.add(reply);
}
}


[ 왜 생성자를 넣을까? ]

외부값 (App1) 에서 매개변수로 받아와서, User 객체의 필드값으로 쳐야하니까!!
@AllArgsConstructor을 하면 안되는 이유는, 모든 필드값을 받아와서 풀생성자로 만드는게 아니라
일부만 생성자로 받을거라서! @AllArgsConstructor가 안 됨!
Share article