아직 와이어프레임이나 주요기능이 정해지지가 않아서 31일에 진행한 유스콘을 살짝 봤습니다.
클린아키텍쳐와 자바와 코틀린에 대해 설명한 부분을 봤는데
클린 아키텍쳐 부분은 지금 당장 적용이 가능할 것 같아 팀원들에게 함께 보자고 했습니다.
일부분은 당장 적용하기로 했습니다.
아직 와이어프레임이나 주요기능이 정해지지가 않아서 31일에 진행한 유스콘을 살짝 봤습니다.
클린아키텍쳐와 자바와 코틀린에 대해 설명한 부분을 봤는데
클린 아키텍쳐 부분은 지금 당장 적용이 가능할 것 같아 팀원들에게 함께 보자고 했습니다.
일부분은 당장 적용하기로 했습니다.
다행히 좋은 팀원들을 만나게 되어서 실전 프로젝트에 대한 걱정 하나는 놓게 되었습니다.
디자이너분도 열정이 넘치셔서 좋습니다.
저녁 8시에 디자이너님이 오신다고 하셔서 그전까지 실전 프로젝트 그라운드 룰을 정하고 백엔드 끼리 따로 회의를 해서 예외 처리와 응답 방식에 대한 컨벤션을 정했습니다.
아이디어에 대한 회의는 하루종일 계속 되었습니다.
저녁 회의를 통해 각자의 아이디어를 공유하고 투표를 통해 하나를 정했습니다.
저희팀은 디자이너 포함 총 6명으로 백엔드 3명, 프론트엔드 2명입니다.
다들 잘하는 분들이고 아이디어도 많고 하고싶은것도 많은 열정피플들이라 의견조율하는데 오래걸리긴 했지만
결국 결론을 냈고 기획을 했습니다.
실전 6주동안 좋은 프로젝트가 나오길 바라면서 최선을 다하도록 하겠습니다.
TIL 최종프로젝트 와이어프레임 짜기 230102 (0) | 2023.01.02 |
---|---|
TIL New year, New Me? 230101 (0) | 2023.01.02 |
TIL 첫 클론 프로젝트 끝 221229 (0) | 2022.12.30 |
TIL 카카오로그인 구현 완성 프론트랑 연결하기 221228 (0) | 2022.12.29 |
TIL BeanCreationException 과 Oauth 2221227 (1) | 2022.12.27 |
잘했음.
TIL New year, New Me? 230101 (0) | 2023.01.02 |
---|---|
TIL 실전프로젝트 첫 회의 221230 (0) | 2022.12.30 |
TIL 카카오로그인 구현 완성 프론트랑 연결하기 221228 (0) | 2022.12.29 |
TIL BeanCreationException 과 Oauth 2221227 (1) | 2022.12.27 |
TIL 카카오로그인 221226 (0) | 2022.12.27 |
오늘은 카카오로그인을 스프링으로 구현하고 프론트와 연결해서 잘 작동하는 것을 확인했습니다. 생각보다 여러가지 시행착오를 많이 겪었지만 결국에는 해냈습니다. 이제 예외처리만 하고 자려고합니다.
하루종일 왜 안되지하다가 오 되네?로 바뀌었습니다.
역시 낮잠이 최고야.
코드 자체는 강의에서 온 거라 그냥 복붙 수준이긴 했습니다만 카카오 디벨로퍼 설정이라던지 프론트와의 연결을 위한 redirect uri 등 설정해주어야 할 것들이 많이 있었습니다. 코드는 아래와 같습니다.
@Slf4j
@RequiredArgsConstructor
@Service
public class KakaoService {
private final PasswordEncoder passwordEncoder;
private final MemberRepository memberRepository;
private final JwtUtil jwtUtil;
@Value("${kakao.client.id}")
private String kakaoClientId;
@Value("${kakao.redirect.uri}")
private String kakaoRedirectUri;
public Response kakaoLogin(String code, HttpServletResponse response) throws JsonProcessingException {
// 1. "인가 코드"로 "액세스 토큰" 요청
String accessToken = getToken(code);
// 2. 토큰으로 카카오 API 호출 : "액세스 토큰"으로 "카카오 사용자 정보" 가져오기
SocialMemberInfo kakaoMemberInfo = getKakaoMemberInfo(accessToken);
// 3. 필요시에 회원가입
Member kakaoMember = registerKakaoMemberIfNeeded(kakaoMemberInfo);
// 4. JWT 토큰 반환
String createToken = jwtUtil.createAccessToken(kakaoMember.getName());
response.addHeader(JwtUtil.AUTHORIZATION_ACCESS, createToken);
return new Response(200, "로그인 성공", createToken);
}
// 1. "인가 코드"로 "액세스 토큰" 요청
private String getToken(String code) throws JsonProcessingException {
// HTTP Header 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HTTP Body 생성
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "authorization_code");
body.add("client_id", kakaoClientId);
body.add("redirect_uri", kakaoRedirectUri);
body.add("code", code);
// HTTP 요청 보내기
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
new HttpEntity<>(body, headers);
RestTemplate rt = new RestTemplate();
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token",
HttpMethod.POST,
kakaoTokenRequest,
String.class
);
// HTTP 응답 (JSON) -> 액세스 토큰 파싱
String responseBody = response.getBody();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(responseBody);
return jsonNode.get("access_token").asText();
}
// 2. 토큰으로 카카오 API 호출 : "액세스 토큰"으로 "카카오 사용자 정보" 가져오기
private SocialMemberInfo getKakaoMemberInfo(String accessToken) throws JsonProcessingException {
// HTTP Header 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + accessToken);
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HTTP 요청 보내기
HttpEntity<MultiValueMap<String, String>> kakaoMemberInfoRequest = new HttpEntity<>(headers);
RestTemplate rt = new RestTemplate();
ResponseEntity<String> response = rt.exchange(
"https://kapi.kakao.com/v2/user/me",
HttpMethod.POST,
kakaoMemberInfoRequest,
String.class
);
String responseBody = response.getBody();
System.out.println(responseBody);
System.out.println(response);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(responseBody);
String id = jsonNode.get("id").asText();
String name = jsonNode.get("properties")
.get("nickname").asText();
String email = jsonNode.get("kakao_account")
.get("email").asText();
return new SocialMemberInfo(id, email, name);
}
}
그리고 컨트롤러는 아래와 같습니다.
@GetMapping("/login/kakao")
public Response<?> kakaoLogin(@RequestParam String code
, HttpServletResponse response)
throws JsonProcessingException {
return kakaoService.kakaoLogin(code, response);
}
@RequestParam 으로 받아주면 Url에 ?으로 요청을 하게 됩니다.
프론트의 로컬 서버인 localhost:3000을 직접 리액트와 node.js를 다운받아서 사용했습니다.
프론트의 깃헙을 포크해서 제 맥북에서 돌렸습니다.
프론트의 코드를 실행하기 전에 다음과 같이 yarn 을 설치해주었습니다.
sudo yarn install
yarn start
위의 명령어를 입력해주고
localhost:3000을 띄워서 연결을 확인합니다.
카카오 로그인 버튼에 링크를 걸어줬습니다.
객체지향 생활체조라는 걸 배웠습니다.
https://hudi.blog/thoughtworks-anthology-object-calisthenics/
이유와 솔루션으로 정리하는 객체지향 생활체조 원칙
객체지향 생활체조 원칙 소트웍스 앤솔러지 표지 "어떤 멍청이라도 컴퓨터가 이해할 수 있는 코드는 작성할 수 있다. 좋은 프로그래머는 사람이 이해할 수 있는 코드를 작성한다. (Any fool can write
hudi.blog
배울게 너무 많습니다.
튜토리얼은 계속되고있습니다.
https://escapefromcoding.tistory.com/699
Spring에서 예외 처리하기
안녕하세요, oooo 백성규선임입니다. 스프링을 사용하면서 예외처리는 무엇이고 어떻게하는 것인지 공부하면서 조금 더 효율적으로 관리하는 방법에 대해 공유하고자 합니다. 이번 시간에 자바
escapefromcoding.tistory.com
TIL 실전프로젝트 첫 회의 221230 (0) | 2022.12.30 |
---|---|
TIL 첫 클론 프로젝트 끝 221229 (0) | 2022.12.30 |
TIL BeanCreationException 과 Oauth 2221227 (1) | 2022.12.27 |
TIL 카카오로그인 221226 (0) | 2022.12.27 |
TIL WIL 1+6주차 회고 벌써 한해가 지나갔다 221225 (0) | 2022.12.26 |
자바에 대한 이해가 너무나 부족해서 해매고 있는 요즘입니다.
자바의정석으로는 알수없는 스프링의 세계에요. 이제는 그냥 되는대로 그때그때 에러와 에러를 에러와 함께 스프링과 자바에 대한 부족함을 극복하고 있습니다.
위의 사진처럼 에러가 떴습니다. 저는 kakao 로그인을 구현 하려고 했습니다. 지난 주차에서 다른 조원분이 하신 코드를 그대로 가져왔는데 에러가 떴습니다. 어차피 사용자 정보를 User가 아니고 Member로 저장한 거 밖에 다른 게 없다고 생각했기 때문입니다. 그런데!!!! 왜 자꾸 저렇게 에러가 뜨는지 모르겠었어요.
구글 해보니 Bean을 제대로 설정해주지 않아서, 제대로 주입해주지 않아서 생긴 문제라고 했습니다.
@Component, @Service, @Controller같은 Bean 등록이 안되있어서 그렇다고 하더라고요. 그런데 확인 결과 해당 어노테이션들은 잘 붙어있었습니다.
저희팀에는 숙련된 조교분이 계십니다.
저희반자체에 컴공 전공하신 분들이 절반이 넘는다고 합니다.
사전스터디가 첫 코딩이었던 (그게 벌써 3개월도 전입니다....) 저와 같은 비전공자 노베이스 분들께는 그저 빛입니다.
제가 하루종일 고민하고 찾아봐도 모르겠었는데 설마 이거겠어 했던게 이거였습니다.
팀원분이 바로 보고 application.properites에 등록했어요? 라고 문제를 찾아내셨습니다.
encryptor와 kakao 관련해서 properties를 추가했고 @value로 보안관련 키값들을 저장해놨습니다.
그걸 사용하려면 application.properties에
spring.profiles.include=
에 값을 넣어주어야합니다.
저희는 applicaiton.properties파일에 아래와 같이 파일들이 들어있기 때문에
spring.profiles.include= dev, kakao, encryptor
라고 써줘야 해당 값들을 불러와서 쓸 수 있었습니다.
BeanCreationException에서 아래 자료도 참고하면 좋을듯합니다.
https://www.baeldung.com/spring-beancreationexception
1. Oauth에 클라이언트가 Authorization code 요청
2. Oauth가 redirect uri를 통해 클라이언트에 Authorization code 부여
3. 클라이언트가 Authorization code 를 서버에 전달
4. 서버가 Authorization code를 Oauth에 보내서 Acess token 요청
5. OAuth가 Acesstoken을 서버에 부여
6. 서버는 클라이언트에 Acess token을 전달
위와 같은 과정을 거쳐 소셜 로그인을 하게됩니다.
저는 카카오 로그인을 맡았는데
프론트에 accesstoken을 발급받아서 백에 전달하는 식으로 진행을 할 거라
프론트분들과 보조를 맞춰야해서 아직 서버 연결은 못해봤지만 코드는 완성했고 멀쩡히 실행은 됩니다.
다음주부터 실전 주차인데
아이디어들은 많습니다. 개발자분들은 기획은 관심없고 기술 구현에만 관심이 있으신듯한데 경영학도 출신인 저는 기획이 잘 되야 만드는 보람이 있을 것 같습니다.
오늘 떠오른 아이디어는 소개팅앱입니다.
매칭되면 만나기 전에 화상 채팅해서 괜한 발걸음 할 필요 없는 그런 소개팅 앱을 구상해봤습니다.
적당히 자격조건을 걸어서 회원 가입 자격도 주고요.
TIL 첫 클론 프로젝트 끝 221229 (0) | 2022.12.30 |
---|---|
TIL 카카오로그인 구현 완성 프론트랑 연결하기 221228 (0) | 2022.12.29 |
TIL 카카오로그인 221226 (0) | 2022.12.27 |
TIL WIL 1+6주차 회고 벌써 한해가 지나갔다 221225 (0) | 2022.12.26 |
TIL 깃헙 활용해서 협업하기 (Feat. mapStruct) 221224 (0) | 2022.12.24 |
이거 쉽지 않네요.
기존에 다른 조원분들이 하셨던 코드를 참조하는데 이해가 안되서 한참을 들여다봅니다. 내일까지 완성해보려고 해요.
검색 기능도 좀 해보면 좋을 듯 해서 찾아보려구요.
TIL 카카오로그인 구현 완성 프론트랑 연결하기 221228 (0) | 2022.12.29 |
---|---|
TIL BeanCreationException 과 Oauth 2221227 (1) | 2022.12.27 |
TIL WIL 1+6주차 회고 벌써 한해가 지나갔다 221225 (0) | 2022.12.26 |
TIL 깃헙 활용해서 협업하기 (Feat. mapStruct) 221224 (0) | 2022.12.24 |
TIL 클론 코딩 기획하기 221223 (0) | 2022.12.24 |
엄밀히 말하면 며칠 남았지만 그래도 세월이 빠르다는 점은 부정할 수 없는 사실입니다.
처음으로 백앤드 프론트앤드가 함께 협업을 했고 결과물을 만들어냈습니다.
TIL 첫 미니프로젝트 회고 221222
https://github.com/faulty337/CatsAndDogs-BE GitHub - faulty337/CatsAndDogs-BE Contribute to faulty337/CatsAndDogs-BE development by creating an account on GitHub. github.com ReadMe 정리 아무도 안하시니까 제가 이번 주중이나 올해가 가
pizzathedeveloper.tistory.com
또 이번주차 새로운 프로젝트를 시작했습니다.
TIL 클론 코딩 기획하기 221223
세세한 것들까지 다 정해서 하느라 기획을 하루종일 했습니다. 9 to 9 full 로 기획하고 나왔습니다. 재주상회라는 사이트를 클론하기로 했습니다. 콘텐츠그룹 재주상회 콘텐츠그룹 재주상회는 미
pizzathedeveloper.tistory.com
깃헙을 이용해서 협업도 합니다.
TIL 깃헙 활용해서 협업하기 (Feat. mapStruct) 221224
이번 주차에서는 팀원들과의 논의 끝에 깃헙을 더 많이 활용해서 협업을 하기로 했습니다. 그래서 다음과 같이 진행이 됩니다. 1. 깃헙에서 이슈 만들기 2. 로컬에서 feature/#이슈번호 브랜치를 만
pizzathedeveloper.tistory.com
마케팅 포인트로 이 부트캠프는 프로젝트를 4개 한다였는데 사실은 1개라고 합니다. 1주짜리는 포트폴리오가 될 수 없고 마지막에 하는 6주짜리 프로젝트 하나에 영혼을 갈아넣어 취업용 프로젝트를 만들어야 한다고 합니다. 잘 모르는 비전공자한테는 다소 당황스럽습니다. 근데 뭐 이것도 말하기 나름이겠지요.
이번주차랑 지난주차는 잠시 쉬어가면서 실전주차 프로젝트를 위한 연습입니다.
이제 끝까지 고수하던 긴 손톱을 제거하고 개발자 면접용 손톱으로 바꾸고 취업을 준비해야겠네요.
다시 취준생이 된 것은 스트레스지만 새로운 것을 도전한다는 것은 언제나 신나는 일입니다.
TIL BeanCreationException 과 Oauth 2221227 (1) | 2022.12.27 |
---|---|
TIL 카카오로그인 221226 (0) | 2022.12.27 |
TIL 깃헙 활용해서 협업하기 (Feat. mapStruct) 221224 (0) | 2022.12.24 |
TIL 클론 코딩 기획하기 221223 (0) | 2022.12.24 |
TIL 첫 미니프로젝트 회고 221222 (0) | 2022.12.24 |
이번 주차에서는 팀원들과의 논의 끝에 깃헙을 더 많이 활용해서 협업을 하기로 했습니다. 그래서 다음과 같이 진행이 됩니다.
1. 깃헙에서 이슈 만들기
2. 로컬에서 feature/#이슈번호 브랜치를 만들어서 작업하기
3. 푸시하기
4. 해당 이슈에 PR 날리기
오늘은 깃헙이슈를 사용해서 작업을 마쳤습니다. 생각보다 체계적이여서 좋습니다. Mapper도 처음 써봤습니다.
예외처리에 대해서도 이야기를 나누고 왠만하면 자바에 있는 기본 예외 처리를 쓰기로 했습니다.
@Component
public class ProductMapper {
public static ProductDetailResponse toResponse(Product product){
return ProductDetailResponse.builder()
.productId(product.getProductId())
.name(product.getName())
.price(product.getPrice())
.caption(product.getCaption())
.bigThumbnailImgUrl(product.getBigThumbnailImgUrl())
.detailImgUrl(product.getDetailImgUrl())
.build();
}
}
매퍼는 팀원분의 코드를 좀 빌려왔습니다. Mapstruct이란 게 있어서 @Mapper 어노테이션을 쓰면 쉽다고 하는데 하루종일보는데 너무 피곤해서 못하겠어서 2시간 낮잠자고 나니까 머리가 맑아져서 금방 기능 완성했습니다.
컨디션 안좋을 땐 낮잠을 자는게 최고인듯 합니다.
오늘은 크리스마스이브여서 10시전에 퇴근했습니다.
TIL 카카오로그인 221226 (0) | 2022.12.27 |
---|---|
TIL WIL 1+6주차 회고 벌써 한해가 지나갔다 221225 (0) | 2022.12.26 |
TIL 클론 코딩 기획하기 221223 (0) | 2022.12.24 |
TIL 첫 미니프로젝트 회고 221222 (0) | 2022.12.24 |
TIL 자바가 모잘라 221221 (0) | 2022.12.22 |
세세한 것들까지 다 정해서 하느라 기획을 하루종일 했습니다. 9 to 9 full 로 기획하고 나왔습니다.
재주상회라는 사이트를 클론하기로 했습니다.
콘텐츠그룹 재주상회
콘텐츠그룹 재주상회는 미디어, 브랜딩과 디자인, 상품개발, 공간개발과 관리 등의 사업 영역을 운영합니다.
iiinjeju.com
왠지 근데 이거 무료툴로 만든거 같기도한데
흠
이번에는 지난 주차와 다르게
모든 도메인을 기술만 나눠서 파트를 분배하였습니다.
자바 컨벤션도 정하고 이것저것 정하고 응답 컨벤션, 커밋 등등....
또 이렇게 새로운 팀원들과 함께하니 배우는 것들이 많아서 좋습니다.
제가 미쳐 알지 못한(아마 대부분의 모든 지식들)것들에 대해 어떤식으로 활용하고 왜 쓰는지에 대한 대화를 나누었습니다.
에러 처리에 대해서도 왜 굳이 customexception을 만들어야하는지에 대해서도 논의를 했는데 저는 당연히 개발자 쓰기 편하라고 하는거 아닌가였는데 새로운 관점으로 생각하게 되었습니다.
협업에 대해서 알아가는 과정이 나름 신선하고 재미있습니다.
TIL WIL 1+6주차 회고 벌써 한해가 지나갔다 221225 (0) | 2022.12.26 |
---|---|
TIL 깃헙 활용해서 협업하기 (Feat. mapStruct) 221224 (0) | 2022.12.24 |
TIL 첫 미니프로젝트 회고 221222 (0) | 2022.12.24 |
TIL 자바가 모잘라 221221 (0) | 2022.12.22 |
TIL Cascade 영속성 전이 비교 분석 221220 (0) | 2022.12.20 |
https://github.com/faulty337/CatsAndDogs-BE
GitHub - faulty337/CatsAndDogs-BE
Contribute to faulty337/CatsAndDogs-BE development by creating an account on GitHub.
github.com
ReadMe 정리 아무도 안하시니까 제가 이번 주중이나 올해가 가기전에 하도록 할게요.
좋은 팀원들과 좋은 경험이었습니다.
TIL 깃헙 활용해서 협업하기 (Feat. mapStruct) 221224 (0) | 2022.12.24 |
---|---|
TIL 클론 코딩 기획하기 221223 (0) | 2022.12.24 |
TIL 자바가 모잘라 221221 (0) | 2022.12.22 |
TIL Cascade 영속성 전이 비교 분석 221220 (0) | 2022.12.20 |
TIL 스프링 좋아요 수 세기와 게시물 삭제 CASCADE 영속성 전이 221219 (0) | 2022.12.19 |
public interface Comparator {
int compare(Object o1, Object o2); //o1, o2 두 객체 비교
boolean equals(Object obj); //equals를 오버라이딩하라는 뜻
}
public interface Comparable {
int compareTo (Object o); // 주어진 객체 o 를 자신과 비교
}
public final class Integer extends Number implements Comparable {
...
public in t compareTo(Integer anotherInteger) {
int v1 = this.value;
int v2 = anotherInteger.value;
//같으면 0, 오른쪽값이 크면 -1, 작으면 1을 반환
return (v1 < v2 ? -1: (v1==v2? 0 :1));
}
...
}
import java.util.*;
class Ex11_7 {
public static void main(String[] args) {
String[] strArr = {"cat", "Dog", "lion", "tiger"};
Arrays.sort(strArr); // String의 Comparable 구현에 의한 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 상관 없이 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, new Descending()); //역순으로 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
}
}
class Descending implements Comparator {
public int compare(Object o1, Object o2){
if( o1 instanceof Comparable && o2 instanceof Comparable) {
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2;
return c1.compareTo(c2) * -1 ; //-1을 곱해서 기본 정렬방식의 역으로 변경
// 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 됨
}
return -1;
}
}
static void sort(int[] intArr) {
for(int i=0; i<intArr.length-1;i++) {
for(int j=0; j<intArr.length-1-i; j++) {
int tmp =0;
if(intArr[j] > intArr[j+1]) {
tmp = intArr[j];
intArr[j] = intArr[j+1];
intArr[j+1] =tmp;
}
}
}
https://gyoogle.dev/blog/algorithm/Bubble%20Sort.html
거품 정렬(Bubble Sort) | 👨🏻💻 Tech Interview
거품 정렬(Bubble Sort) Goal Bubble Sort에 대해 설명할 수 있다. Bubble Sort 과정에 대해 설명할 수 있다. Bubble Sort을 구현할 수 있다. Bubble Sort의 시간복잡도와 공간복잡도를 계산할 수 있다. Abstract Bubble S
gyoogle.dev
남궁성 자바의 정석 ch 11 Iterator, ListIterator, Enumeration (0) | 2022.12.22 |
---|---|
남궁성 자바의정석 ch 11 Stack & Queue (0) | 2022.12.22 |
남궁성 자바의정석 기초편 ch 11 LinkedList (0) | 2022.12.22 |
남궁성 자바의 정석 기초편 Ch 11 ArrayList (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch11 컬렉션 프레임웍 collections framework (0) | 2022.12.21 |
List list = new ArrayLsit(); //다른 컬렉션으로 변경할 때는 이 부분만 고치면 된다.
Iterator it = list.interator();
while(it.hasNext()) { //boolean has Next()
System.out.println(it.next());
}
Map map = new HashMap();
.
.
.
Iterator it = map.entrySet().iterator();
남궁성 자바의 정석 기초편 ch 11 Arrays Comparator Comparable (0) | 2022.12.22 |
---|---|
남궁성 자바의정석 ch 11 Stack & Queue (0) | 2022.12.22 |
남궁성 자바의정석 기초편 ch 11 LinkedList (0) | 2022.12.22 |
남궁성 자바의 정석 기초편 Ch 11 ArrayList (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch11 컬렉션 프레임웍 collections framework (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch 11 Arrays Comparator Comparable (0) | 2022.12.22 |
---|---|
남궁성 자바의 정석 ch 11 Iterator, ListIterator, Enumeration (0) | 2022.12.22 |
남궁성 자바의정석 기초편 ch 11 LinkedList (0) | 2022.12.22 |
남궁성 자바의 정석 기초편 Ch 11 ArrayList (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch11 컬렉션 프레임웍 collections framework (0) | 2022.12.21 |
class Node{
Node next;
Object obj;
}
class Node{
Node next;
Node previous;
Object obj;
}
남궁성 자바의 정석 ch 11 Iterator, ListIterator, Enumeration (0) | 2022.12.22 |
---|---|
남궁성 자바의정석 ch 11 Stack & Queue (0) | 2022.12.22 |
남궁성 자바의 정석 기초편 Ch 11 ArrayList (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch11 컬렉션 프레임웍 collections framework (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch 7 디폴트 메서드 static 메서드 (0) | 2022.12.01 |
자바가 모잘라서 자바 공부를 합니다.
사실 서버 배포도 공부해야하는데 자바를 모르는게 더 시급하다고 생각해서 자바의 정석을 들었습니다.
Map, List, Set, Stream 등등 이번주는 컬렉션 프레임웍 뽀개기를 할겁니다.
그다음에 Spring 강의도 들어야겠습니다.
오늘은 전체 코드를 refactoring을 하고 발표자료를 만들었습니다. 다들 엄청 잘하셔서 든든합니다.
데이터에 좋아요 수를 넣어서 보내주는 것으로 변경했습니다.
@Transactional
public LikePostResponseDto likePost(Long postId, User user) {
Post post = postRepository.findById(postId).orElseThrow(
() -> new CustomException(ErrorCode.CONTENT_NOT_FOUND)
);
Long userId = user.getId();
boolean likeCheck;
Optional <LikePost> likePost = likePostRepository.findByPostIdAndUserId(postId, userId);
if (likePost.isPresent()) {
LikePost like = likePost.get();
likePostRepository.delete(like);
post.setLikeCount(post.getLikeCount()-1);
likeCheck = false;
} else{
LikePost like = new LikePost(postId, userId);
likePostRepository.save(like);
post.setLikeCount(post.getLikeCount()+1);
likeCheck = true;
}
return new LikePostResponseDto(likeCheck, post.getLikeCount());
}
@ApiOperation(value = "게시글 좋아요")
@PostMapping("/post/{postId}")
public ResponseEntity<ResponseMessage> likePost(@PathVariable Long postId, @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails){
LikePostResponseDto likePostResponseDto = likeService.likePost(postId, userDetails.getUser());
ResponseMessage<LikePostResponseDto> responseMessage = new ResponseMessage<>("게시글 좋아요 성공", 200, likePostResponseDto);
return new ResponseEntity<>(responseMessage, HttpStatus.valueOf(responseMessage.getStatusCode()));
}
@Getter
@Setter
@NoArgsConstructor
public class LikePostResponseDto {
private boolean postLiked;
private Long likeCount;
public LikePostResponseDto(boolean postLiked, Long likeCount) {
this.postLiked = postLiked;
this.likeCount = likeCount;
}
}
TIL 클론 코딩 기획하기 221223 (0) | 2022.12.24 |
---|---|
TIL 첫 미니프로젝트 회고 221222 (0) | 2022.12.24 |
TIL Cascade 영속성 전이 비교 분석 221220 (0) | 2022.12.20 |
TIL 스프링 좋아요 수 세기와 게시물 삭제 CASCADE 영속성 전이 221219 (0) | 2022.12.19 |
TIL/WIL CORS 221218 (0) | 2022.12.19 |
list1:[0,1,2,3,4,5]
list2:[0,2,4]
list1.containsAll(list2):true
containsAll: 포함하고 있는지 true/false 반환 하는 메서드
list1.remove(1) // 인덱스가 1인 객체를 삭제
list1.remove(new Integer(1)); // 1을 삭제
- 마지막 객체부터 삭제하면 됨
남궁성 자바의정석 ch 11 Stack & Queue (0) | 2022.12.22 |
---|---|
남궁성 자바의정석 기초편 ch 11 LinkedList (0) | 2022.12.22 |
남궁성 자바의 정석 기초편 ch11 컬렉션 프레임웍 collections framework (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch 7 디폴트 메서드 static 메서드 (0) | 2022.12.01 |
남궁성 자바의 정석 기초편 ch 7 인터페이스 interface (0) | 2022.12.01 |
컬렉션 프레임웍의 핵심 인터페이스
남궁성 자바의정석 기초편 ch 11 LinkedList (0) | 2022.12.22 |
---|---|
남궁성 자바의 정석 기초편 Ch 11 ArrayList (0) | 2022.12.21 |
남궁성 자바의 정석 기초편 ch 7 디폴트 메서드 static 메서드 (0) | 2022.12.01 |
남궁성 자바의 정석 기초편 ch 7 인터페이스 interface (0) | 2022.12.01 |
남궁성 자바의 정석 기초편 ch 7 추상클래스 추상메서드 (0) | 2022.11.30 |
영속성 전이를 사용하거나 for문을 돌려서 순수 자바만을 사용했을 때는 아래처럼 일일히 데이터마다 쿼리를 날려서 지우게 했습니다. 지금은 그 수가 적어서 상관이 없지만 나중에 대용량 데이터를 다루게 될 때에 과부하가 걸릴 수도 있다는 판단이 들었습니다.
where in 을 사용해서 query를 날리면 댓글을 하나하나 삭제를 하는 것이아니라 한번에 날려줍니다.
public interface CommentRepository extends JpaRepository<Comment, Long>{
@Modifying //기존에 있는 메서드를 변경하기 때문에
@Query("delete from Comment c where c.id in :ids")
void deleteAllByIdIn(@Param("ids") List<Long> ids);
}
위의 코드는 where in을 사용해서 comment와 Likecomment, likepost, post 를 한번씩만 쿼리를 날려서 관련 목록을 다 삭제하였습니다.
다음에 코드 정리해서 포스팅 해보도록 하겠습니다.
참고블로그:
JPA에서 대량의 데이터를 삭제할때 주의해야할 점
안녕하세요? 이번 시간엔 JPA에서 대량의 데이터를 삭제할때 주의해야할 점을 샘플예제로 소개드리려고 합니다. 모든 코드는 Github에 있기 때문에 함께 보시면 더 이해하기 쉬우실 것 같습니다. (
jojoldu.tistory.com
TIL 첫 미니프로젝트 회고 221222 (0) | 2022.12.24 |
---|---|
TIL 자바가 모잘라 221221 (0) | 2022.12.22 |
TIL 스프링 좋아요 수 세기와 게시물 삭제 CASCADE 영속성 전이 221219 (0) | 2022.12.19 |
TIL/WIL CORS 221218 (0) | 2022.12.19 |
TIL 좋아요는 사랑입니다❤️ 221217 (0) | 2022.12.17 |
주말에 오랜만에 놀았더니 오전에 집중하는 게 힘들었던 월요일입니다. 점심시간에 파워냅 1시간 하고 돌아와서 다시 정신 차리고 합니다. 오늘은 영하 15도까지 내려갔다고 하네요. 집에 보일러가 고장나서 슬픈 캥거루족입니다. 얼른 개발자로 취직해서 판교에서 자취하고 싶어요. 어제 오랜만에 대학 친구들을 만났는데 한 친구가 미국 온라인 대학원을 다니고 있다는 소식을 들었습니다. 오프라인과 같은 학위를 받지만 전체 온라인 수업이라 학비도 상대적으로 저렴했습니다. 저도 나중에 취업하고 다녀볼까봐요. BBA & 컴공 master?!
좋아요를 하고 취소하는 API를 만들어 놓고 정작 좋아요 갯수를 세는 기능이 없어서 오늘은 좋아요 갯수 세는 기능을 추가했습니다.
생각보다 간단해서 낮잠 자고 멀쩡한 정신으로 해결했습니다. 다음과 같이 @Service에 코드를 추가했습니다.
Long likeCount = likePostRepository.countByPostId(postId);
post.setLikecount(post.getLikeCount()-1);
Long likeCount = likePostRepository.countByPostId(postId);
post.setLikecount(post.getLikeCount()+1);
숫자를 저장할 Long 타입 변수를 만들고 해당 게시물 Id를 이용해서 좋아요 수를 저장했습니다.
post Entity에 있는 Likecount 변수에 넣어주었습니다.
Comment를 좋아요 한 변수는 처음에 0으로 설정해서 Nullpointerexception error를 방지합니다.
조장님이 던져준 미션인 cascade.remove를 사용하지 않고 게시물 삭제와 동시에 연관된 좋아요, 댓글, 댓글좋아요를 삭제하는 방법에 대해 연구했습니다. Cascade를 사용하면 연관된 테이블이 자동으로 함께 지워진다는 편리함이 있지만 주의해야할 점이 있습니다.
이에 대해 인프런 JPA 강의 Q&A에서 김영한님의 친절한 답변이 다음과 같이 달렸습니다.
cascade 옵션은 단순히 생각하면, 그냥 persist() 호출을 줄여줄 수 있기 때문에, 유용해 보이지만, 반대로 생각하면, Order 엔티티를 저장할 때, 연관된 어떤 엔티티들이 함께 저장될까? 를 계속 코드를 보며 추적해야 합니다.
따라서 질문하신 것 처럼 어디까지는 cascade로 함께 저장하고, 어디까지는 함께 저장하면 안될까? 하는 명확한 기준이 필요합니다.
그래서 이런 기준을 잡기 애매한 경우에는 사실 사용하지 않는 것이 좋습니다.
통상적으로 권장하는 cascade 범위는, 완전히 개인 소유하는 엔티티일 때, 예를 들어서 게시판과 첨부파일이 있을 때 첨부파일은 게시판 엔티티만 참조하므로, 개인 소유 입니다. 이런 경우에는 사용해도 됩니다. 그럼 반대로 개인 소유하지 않는 엔티티는 무엇일까요? 예를 들어서, 회원, 상품 등등이 있습니다.
이 예제에서 Order -> OrderItem을 개인소유 하기 때문에 cascade를 사용했습니다. 그런데 Order 입장에서 Delivery는 좀 애매합니다. 여기서는 프로젝트 규모가 작기 때문에 매우 단순하게 표현했지만, 실무에서 프로젝트 규모가 커지면, Delivery로 여러곳에서 참조될 수 있습니다. 그러면 사용하면 안됩니다.
추가로 도메인 주도 설계(DDD)의 Aggregate Root 개념을 이해하고, 프로젝트 적용하면 여기에 맞추어 cascade 옵션을 더 잘 활용할 수 있습니다.
정리하면
1. 완전 개인 소유인 경우에 사용할 수 있다.
2. DDD의 Aggregate Root와 어울린다.
3. 애매하면 사용하지 않는다.
더 자세한 내용은 JPA 기본편 섹션 8에 있는 영속성 전이(CASCADE)와 고아 객체를 참고해주세요.
감사합니다.
출처:
https://www.inflearn.com/questions/31969/cascade-%EC%98%B5%EC%85%98-%EC%A7%88%EB%AC%B8
1. 완전 개인 소유인 경우에 사용할 수 있다.
2. DDD의 Aggregate Root와 어울린다.
3. 애매하면 사용하지 않는다.
제가 봉착한 문제는 Cascade의 저 조건에 부합하지 않는(완전 개인의 소유가 아닌)
comment(한 게시물에 여러 댓글 여러 회원)는 deleteAllByPostId로 삭제하고
postLike(포스트에는 댓글과 좋아요가 있음)도 deleteAllbyPostId로 삭제를 하고
comment(댓글은 게시글과 게시글좋아요와 댓글좋아요가 있음)도 deleteAllbyPostId로 삭제를하고
Likecomment는 ...
comment와 likecomment 뿐입니다.
post를 지울때 likecomment를 cascade를 사용하지 않고 지운다면
post의 모든 comment의 id값을 각각 불러와서 그에 맞는 like값을 deleteAllbycommentId를 해야하는데
commentlist를 조회해서 그들의 Id값을 뽑아서 그들의 Id값에 따른 Likelist를 찾아서 삭제를 해줘야합니다.
그래서 제가 생각한 것은 comment와 Likecomment만 cascade.remove를 사용해도 되지 않겠냐는 겁니다.
댓글과 댓글좋아요의 관계에서 댓글좋아요는 댓글만을 참조하기 때문에 cascade를 사용해도 되겠다고 판단했습니다.
저는 중첩 for문 돌리는 것을 그렇게 좋아하는 편은 아닙니다.
CASCADE를 사용한다면,
연관관계설정을 다시 한 후 해야겠고요.
기술매니저님께 여쭤본 결과, where in 이라는 방법으로 N+1 을 해결 할 수 있다고 합니다.
각각의 방법을 비교해서 정리해보라는 조언을 주셨습니다. 각 방법 별로 성능이 달라질 수도 있다고 합니다.
내일은 이것만 파야겠네요.
일단 끝.
Spring 강의 좀 보다가 자야겠습니다.
TIL 자바가 모잘라 221221 (0) | 2022.12.22 |
---|---|
TIL Cascade 영속성 전이 비교 분석 221220 (0) | 2022.12.20 |
TIL/WIL CORS 221218 (0) | 2022.12.19 |
TIL 좋아요는 사랑입니다❤️ 221217 (0) | 2022.12.17 |
TIL 첫 포트폴리오 프로젝트 시작 221216 (0) | 2022.12.17 |
CORS(Cross-Origin Resource Sharing)
[WEB] 📚 악명 높은 CORS 개념 & 해결법 - 정리 끝판왕 👏
악명 높은 CORS 에러 메세지 웹 개발을 하다보면 반드시 마주치는 멍멍 같은 에러가 바로 CORS 이다. 웹 개발의 신입 신고식이라고 할 정도로, CORS는 누구나 한 번 정도는 겪게 된다고 해도 과언이
inpa.tistory.com
CORS는 위의 블로그 글을 참조하면 됩니다.
TIL Cascade 영속성 전이 비교 분석 221220 (0) | 2022.12.20 |
---|---|
TIL 스프링 좋아요 수 세기와 게시물 삭제 CASCADE 영속성 전이 221219 (0) | 2022.12.19 |
TIL 좋아요는 사랑입니다❤️ 221217 (0) | 2022.12.17 |
TIL 첫 포트폴리오 프로젝트 시작 221216 (0) | 2022.12.17 |
TIL JPA 마스터의 길 게시글 댓글 연관 관계 만들기 221215 (0) | 2022.12.15 |