http://13.125.105.236/
위 사이트 개발에 대한 정리글입니다. (AWS 배포가 중단되면 접속이 제한될 수 있습니다)
https://github.com/shyswy/Community-Site
GitHub - shyswy/Community-Site: Simple community Site
Simple community Site. Contribute to shyswy/Community-Site development by creating an account on GitHub.
github.com
위 링크는 프로젝트 리포지토리입니다. README를 자세히 작성했으니 참고하시면 됩니다.
DTO: 각 계층간 정보 전달시 필요한 정보만 담아 전달.
Ex: BoardDTO: 게시물(Board)에서 필요한 정보 모음. ( 게시물 내용+ 작성자 정보+ replyCount)
Html: 컨트롤러에게 어떠한 정보를 전달받을 때, DTO로 받는다. ( 엔티티를 주는건 너무 무겁다.
필요한 정보만 담은 DTO 타입으로 전받받는다.)
Controller:
- front가 요청한, 또는 필요한 정보를 DTO로 전송
- Html등 front에서 받은 정보기반 적정한 Service의 메소드 사용
Service : Serviceimpl의 기본적인 틀( 메소드, 변수 선언 등)
+ 가끔 Dto TO Entity 메소드를 작성하기도
( default 리턴 타입 func() {} ; >> 이렇게 default를 통해 interface에서도 함수 정의 가능해졌다.)
ServiceImpl: 실제 Service 기능 구현됨. 여기서 직접적으로 Repository에 save() 등을 수행하려면,
DTO 타입이 아닌, Entity로 다시 변경해줘야하기에 DtoToEntity 메소드를 사용해서 바꿔줘야한다.
왜 Service 인터페이스를 사용? >> 불변성을 위해. 대략적인 틀이 바뀌지 않는 기점을 세운다.
해당 틀만 유지한채, 자유롭게 변경해서 사용할 수 도 있다.
Ex: 굼바 인터페이스 >> 가시 굼바, 일반 굼바, 독 굼바 …. 다양한 인스턴스 형성하되,
‘굼바’ 라는 공통된 특성은 유지한다.
Repository: 정보를 영속적으로 저장. 보통 JPARepository를 상속받는데,
여기서 기본적인 Query 메소드들을 사용가능하고, @Query로 새롭게 쿼리 생성가능
>> DB에서 어떠한 정보를 찾아오기
Or 상위 계층에 선언된 save, delete등을 사용해서 DB Modify 가능
Save: repository.save(Entity) >> 해당 Entity를 해당 Repository( DB 테이블) 에 저장.
update
Entity.changeTitle(~~~~~) // 해당 Entity의 특정 파트를 변경. (seter과 유사하게, )
Repository.save(Entity) // 변경사항 저장.
Delete
Repository.deletebyId(Id); 등으로 특정 entity 제거 가능.
보통 특정 엔티티를 db에 저장하는 register의 경우,
Html> 특정 입력정보 DTO 전송 > Controller가 DTO 받아서 Service에
ServiceImpl: Service의 DTO to Entity 함수를 통해 엔티티로 변환 후, save.
P3 : 다대일 관계 : Board
![](https://blog.kakaocdn.net/dn/5zI4v/btrVT7XvWu6/DBHd13KRVGe30vVNyGqS5k/img.png)
Member : board : replay
1 : 다 : 다
@ManytoOne을 통해 다수 쪽이 One 쪽의 객체를 가지지만,
@OnetoMany
List<>~~~ 이런식으로 One 쪽이 Many에 대한 객체를 생성 x 하여 구현함을 가정.
>> 그럼 One쪽에서 Many의 객체를 참조하고 싶다면?
>>JPQL ( @Query ) 에서
*주의 Board 엔티티 객체를 생성시, bno,member의 email은 필수 조건
(bno= 자신의 PK, member(writer) email: F.K 조건. >> 생성시 해당 field값으로 적절한 member객체와 join
BoardRepository 영역에서 만약 자신과
Board : reply
1 대 다
관계인 reply를 가져오고 싶다면
Join on 을 통해서.
![](https://blog.kakaocdn.net/dn/dI90VU/btrVTUYowO8/dLbce4muN9OOG8fu5Q27aK/img.png)
사용예시.
![](https://blog.kakaocdn.net/dn/bpDkgx/btrVRDCCVXh/12PO0Dw6KcHyEdQs9AqmJ0/img.png)
Lazy: 그때그때 필요한 것만 join (권장)
Eager: 완벽하게 모든 연관 관계에 대하여 join, 통째로 가져온다.
Lazy는 테이블을 1개씩 뽑아올 때 좋다. 복잡한 연관관계가 잡혀 있다면, Eager로 한번에 쭉 가져오는 것이 좋은 경우도 존재한다.
>> 기본적으론 Lazy, 특수한 상황에서 적절히 Eager
Ex:
@ManyToOne(fetch=FetchType.LAZY)//Lazy" private Member writer;
>> @ManyToOne ( fetch 타입)
Private Member writer >>> Many 쪽에서 One의 인스턴스를 보유하고, 이 인스턴스를 통해 join 한다.
주의 사항! >> 내가 필요한 정보가 제대 fetch 안될 수 도 있다.
![](https://blog.kakaocdn.net/dn/tn7po/btrVVQ8bMcw/4sWO4lQhBXWcd7h94IaIq1/img.png)
Writer은 Board에 존재하는 Member의 객체.
Board와 Member은 many To one 구조로, board(게시글) 의 writer(작성자) 정보를 가져오려 하지만,
Lazy로 인해 아직 fetch 되지 않는 문제점 발생 >> @Transactional 을 사용해서 한 덩어리로!
Java의 Object 타입: 모든 클래스의 부모가 되는 자바의 최상위 부모 클래스. 모든 클래스를 사용할 수 있다.
Ex: getBoardWithWriter가 해당하는 모든 엔티티 객체들을 리턴 할 때.
![](https://blog.kakaocdn.net/dn/vgzvm/btrVUsf3AYC/rkjE3r5R4yPzD8Za0nun51/img.png)
Select Board , Writer(member 클래스)
>> board, member의 모든 원소들 리턴.
일단 Object 타입으로 받고
![](https://blog.kakaocdn.net/dn/9Yxi5/btrVQPQPFlm/oJzz34xCz5pLdKWSgMTMx0/img.png)
Object 배열로 타입 변환( 모든 타입 사용가능)
>> 그 Object 배열안 각 Object들에 Arrays.toString() 을 통해 Object > string으로 바꿔주자.
![](https://blog.kakaocdn.net/dn/d8rkLH/btrVVff4OT5/0M2wymCFupp338Wi4Alvl1/img.png)
Board, Member 클래스에 @ToString 으로 모든 정보들을 Arrays.toString() 을 통해 변경가능하게 설정했다.
Member < Board < Reply 구조에서, Board( 게시글) 이 연관된 정보 가져오게 만들기
Ex: 어떠한 board(게시글) 의 목록을 만드는데, 각 게시글 마다 그 게시글을 작성한
Writer(Member) 와 그 게시물에 달린 reply 수를 구해서 목록에 저장할 때.
목록>> Pageable 사용!
목표:
각 게시물마다 b(해당하는 게시물) 의 writer, 그리고 객체 b를 보유한 Reply 객체들의 수를 리턴.
>> Board가 중심, Board를 통해 연관된 writer( 객체 보유) Reply(객체 미 보유) 가져와야 한다.
>> writer는 보유한 객체를 가져오면 되고, Reply는 join Reply r on r.board= b 이런식으로
자신을 보유한 reply를 매칭해서 찾으면 된다.
B를 보유한 reply 객체, 즉 logical하게는 b에 달린 reply 수 >> group by를 통해 수를 계산.
+
Pageable 객체로, 일정한 size, 정렬 순서 등등을 객체로 받아 처리하게
>> count 쿼리가 암시적으로 사용되기에 countQuery 정의.
![](https://blog.kakaocdn.net/dn/52ztn/btrVVglLYl9/QOnX1usfGwqjKhWw2tDDSk/img.png)
Page<Object[]> : Object[] 를 담은 객체.
Pageable 객체가 담은 시작 페이지, 페이지 size, 정렬순서 에 기반하여 select 된 정보들을
페이지 단위로 리턴해준다.
Object[] >> select된 정보들이 저장되어있다. 이 경우, Board, Member, Long 3가지 타입이 select되는데, 이 정보가 Object[]에 들어가는 것.
Object[0] >> 선택된 Board 객체
Object[1] >> 선택된 writer
Object[2] >> 선택된 ReplyCount
>> 나중에 사용할 때, type Case로 적절한 타입으로 변환해서 사용.
Pageable 사용법.
![](https://blog.kakaocdn.net/dn/b7ZIYh/btrVQPDjzAl/HqJ1UYt7Po69gakJSPCCj0/img.png)
>> 한 목록에 10개의 Board 객체( 게시물)
@Autowired: 생성자 주입 방식( setter 주입 등보다 이점이 많다)
>> @RequiredArgConstruct(@Data에 포함) 어노테이션을 쓰면 일일이 @Autowired할 필요 없다.
![](https://blog.kakaocdn.net/dn/mnOCj/btrVTmHlu7h/lQCAICmyFdSJX3kgPMAyjk/img.png)
생성자 주입: 인스턴스 생성시 최초 1번만 불려짐. >> 불변!
Setter 주입: setter가 불려질 때마다 변경 가능성 > bad!
![](https://blog.kakaocdn.net/dn/kTQKU/btrVUkvpKza/Ww74cvkP9X2EJmKWiGrZ1k/img.png)
>> Entity 타입, PK 타입( gno, bno 등등)
>> save(Entity ) 에서 Entity를 정의하는 등에서 사용
'Spring boot' 카테고리의 다른 글
Spring security란? (0) | 2023.01.25 |
---|---|
자바 Stream 정리 [Stream, Map, Filtering, Sorted, Collect] (0) | 2023.01.15 |
[toyProject] 게시물 사이트 Part 3 (0) | 2023.01.10 |
[toyProject] 게시물 사이트 Part 2 (0) | 2023.01.10 |
[김영한 스프링 입문] 주요 이론 정리 (0) | 2023.01.10 |