Week 6250203(Mon)250204(Tue)250205(Wed)250208(Sat)Week 7250211(Tue)250212(Wed)250114(Fri)250115(Sat)250116(Sun)Week 8250117(Mon)250118(Tue)250219(Wed)250220(Thu)
Week 6
250203(Mon)
250204(Tue)
250205(Wed)
250208(Sat)
- 솔리드 커넥션 서버 코드 리뷰
Week 7
250211(Tue)
- 소마 지원서 제출…
- 솔리드 커넥션 신규 대학 추가
250212(Wed)
- 솔리드 커넥션 웹 개발
- 애플 로그인 추가
250114(Fri)
- 솔리드 커넥션 웹 개발
- api 엔드포인트 변경에 따른 수정
- 애플 로그인 버그 수정
- 웹 stage 환경 분리/구성
- 솔리드 커넥션 모니터링 인프라 구성
250115(Sat)
- 솔리드 커넥션 관리자 api 관련 코드 리뷰
- 스프링 계열 pagination에 대해 공부할 수 있었다
- https://github.com/solid-connection/solid-connect-server/pull/207
- 솔리드 커넥션 웹 개발
- api 변경에 따른 수정
- 수많은 버그 리포트와 버그 수정…
- 솔리드 커넥션 어드민 페이지 개발
- 일반 react 앱으로 개발 예정
- 기본 패키지 설치, lint/format 설정
- 솔리드 커넥션 앱 개발
- 스캐폴딩 색 문제, 확대 문제 해결
250116(Sun)
- 솔리드 커넥션 웹 개발
- 신규 홈 화면 컴포넌트 추가
- 지원 페이지 다시 추가
- 솔리드 커넥션 앱 개발
- 빌드 후 배포… ios 배포는 잘 모르겠다
Week 8
250117(Mon)
- 솔리드 커넥션 웹 개발
- stage환경 env 설정
- Vercel에서 .env.production은 자동으로 적용되서 Preview에는 .env.development가 자동적용 되지 않을까? 했지만 어림도 없다
- favicon 추가
- svgr 때문에 icon.svg 오류, 고칠방법이 있겠지만 그냥 icon.png로 변경. 이게 문제해결이지 ㅇㅇ
- 사파리 폰트문제 수정
- 성적 공유 페이지 캐싱때문인지 오류, 서버쪽에 이슈 리포트
- api 엔드포인트 오류 수정
- 덧글 새로고침 안되는 버그 수정
- router.refresh()의 원리를 알게되었다
- PUT과 대비한 PATCH의 장점을 확실히 느꼈다
- 이미지 변경이나, 중복 닉네임 변경등…
- 서버사이드 렌더링 revalidate 새로고침 추가(뉴스 페이지)
- 프로그래머스 풀이
- Lv.1 /연습문제/과일 장수
- Lv.2 /2021 KAKAO BLIND RECRUITMENT/순위 검색
- 숫자를 제외하고는 총 3 * 2 * 2 * 2 로 그렇게 많은 경우의수가 있지는 않다
- 트리형태로 탐색 가능하게
- 다만 숫자를 그냥 linear하게 탐색했더니 시간초과가 났다
- 큰 차이가 나지 않을꺼라 생각했는데 조건에 따라 크게 상관 있을 것 같긴 하다
- 전체적으로 파이썬 PS에 익숙해지는 기회가 되었다. bisect도 오랜만에 써보고, 문법도 다시 한번 써보게 됐다
- Celery 오류 해결
250118(Tue)
- mc-archieve 개발
MappedSuperclass
를 이용한 BaseEntity 추가
- Celery 공부
- prefetching과 이의 단점에 관해
- ACK 조건과 acks_late 그리고 RabbitMQ를 사용하지 않는 환경에서의 visibility timeout에 관해
- 자바 ORM 표준 JPA 프로그래밍 - 기본편 학습
- 값 타입
- 엔티티 타입: @Entity로 정의한 객체
- pk값으로 관리되기 때문에 지속적으로 추적하고 관리 가능
- 값 타입: 자바 기본 타입(int, double 등), 래퍼 클래스(Integer, Long 등), String 등
- 생명주기를 엔티티에 의존한다(회원을 삭제하면 이름, 나이 필드도 같이 삭제)
- 같은 값이라고 공유해서는 안됨(이름을 바꾸면 동명이인의 이름도 같이 바뀐다던지)
- primitive type은 항상 값을 복사하니 ok
- 래퍼클래스나 String등은 자바에서 공유를 막을 수는 없기에 변경을 못하게 해서 side effect를 막는다
- 임베디드 타입
- 회원 정보중 주소(city, street, zipcode)를 분리해서 관리하려면 따로 만들어서 @Embeddable를 붙이기
- 이를 사용하는 Member쪽에서는 @Embedded 붙여주기
- 기본 생성자 필수
@Embeddable public class Address { private String city; private String street; private String zipcode; public Address() { // 기본생성자 필수 } } public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME") private String username; @Embedded private Address homeAddress; }
- 잘만든 ORM 앱은 테이블보다 클래스의 수가 더 많다
- 임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험함
- primitive, wrapper, String은 막혀있으니 괜찮지만 임베디드는 직접 정의한 객체이기에 공유/수정이 가능하니 주의
- 불변 객체(immutable object)
- 생성자로만 값을 설정하고 수정자를 만들지 말자
- Integer, String등도 자바가 제공하는 불변 객체
- 바꾸고 싶으면 새로 객체를 생성하자
- 값 타입 컬렉션
- @ElementCollection, @CollectionTable 을 이용
- 값 타입을 하나 이상 저장할 때 사용
- 값 타입을 소유한 엔티티의 생명주기를 따라간다
- 지연로딩으로 작동
- 식별자가 없기 때문에 매번 모든 값 타입 컬렉션은 지우기 다시 쓴다
- 모든 컬럼이 식별자가 되기에 null x, 중복저장 x
- 즉 실무에서는 값 타입 대신 1:N을 고려하는 편
- 소개
- JPA에는 다양한 쿼리방법이 있다: JPQL, QueryDSL, 네이티브 SQL, JDBC API
- JPQL: 객체지향 SQL
- JPA를 사용하면 엔티티 중심으로 개발하는데, 검색쿼리를 날릴 때 문제가 있다. 왜냐면 모든 DB를 객체로 만들고 검색하는 것은 불가능하고 필요한 데이터만 DB에서 불러와야하기 때문
- JPA는 SQL을 추상화한 객체 지향 쿼리 언어 JPQL을 제공
List<Member> result = em.createQuery( "select m from Member m where m.username like '%kim%'", Member.class ).getResultList();
- SQL을 실행해주기전에 수동 flush
- select m from Member as m where m.age > 18
- 엔티티와 속성은 대소문자 구분
- JPQL 문법은 대소문자 미구분
- alias는 필수지만 as는 생략가능(m)
- TypeQuery: 타입이 명확할 때, Query: 타입이 명확하지 않을 때
- query.getResultList(): 결과 하나 이상, query.getSingleResult(): 결과가 하나
- 파라미터 바인딩: 이름 기준 또는 위치 기준으로 적용 가능. 아래는 이름 기준 예시
Member result = em.createQuery("select m from Member m where m.username = :username", Member.class) .setParameter("username", "jayden") .getSingleResult();
- …
- setFirstResult(int startPosition).setMaxResults(int maxResult) 메서드 체이닝 가능
- 경로 표현식
- 상태 필드(state field): 단순히 값을 저장하기 위한 필드(ex: m.username)
- 경로 탐색의 끝, 탐색 X
- 연관 필드(association field): 연관관계를 위한 필드
- 단일 값 연관 필드: @ManyToOne, @OneToOne, 대상이 엔티티(ex: m.team)
- 묵시적 내부 조인(inner join) 발생, 탐색 O
- 컬렉션 값 연관 필드: @OneToMany, @ManyToMany, 대상이 컬렉션(ex: m.orders)
- 묵시적 내부 조인(inner join) 발생, 탐색 X
- FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색 가능
- 예제
- select o.member.team from Order o: 성공
- select t.members from Team t: 성공
- select t.members.username from Team t: 실패
- select m.username from Team t join t.members m: 성공
- 가급적 명시적 조인 사용
- 페치 조인 1 - 기본
- 페치 조인 2 - 한계
- 다형성 쿼리
- 엔티티 직접 사용
- Named 쿼리
- 벌크 연산
250219(Wed)
- mc-archieve 개발, 스프링 공부
- @ManyToOne(optional=false) 과 @JoinColumn(nullable=false) 차이
- optional은 JPA 객체에 관한 것, nullable은 테이블에 관한것. 둘을 일치시키지 않을 이유가 없어보인다. 둘다 적용해주기
- 엔티티 리팩토링
- Many쪽을 연관관계의 주인으로 설정, ManyToOne에서 지연 로딩 설정
- Image를 엔티티에서 Embedded로 전환
- 유저 관련 엔티티는 OneToOne이 많다
- password, player 분리는 필수라 생각하고, profile 분리는 나의 취향…
- 프로필 분리시 @MapsID 로 user와 profile id를 일치시켰다. 나중에 더 공부해볼 것
- Profile에서 Image를 재활용
- 굳이 필요없다 생각했는데, @AttributeOverride로 컬럼명 재지정해줘도 될듯. 나는 이정도면 ok라 생각. 어짜피 Profile도 분리해두었으니
- 레포지토리 구현
- OneToOne에서 Lazy를 쓴다면 어떨까?
- player와 password는 lazy가 맞다 생각해서 분리했다. password는 인증때만 쓸거고, player는 항상 필요한게 아니니. profile은 하나처럼 쓰고자 EAGER로 했다(기본값)
- 다만 one to one에서 연관관계의 주인이 아닌쪽은 Lazy로 설정해도 Eager로 된다는 말이 있다. 큰 문제는 아닌듯. 어짜피 반대 방향에서는 거의 항상 불러 올 것 같아서
- 컨트롤러/서비스 로직 구현
- 스프링 빈을 주입 받을 때 → private final 해주기
- 솔리드 커넥션 모니터링 설정
250220(Thu)
- 솔리드 커넥션 웹 개발/버그 수정
- 성적 제출 타입 문제
- Enum 추가하고 성적 종류 추가해서 해결
- 성적 인증 거절 사유 알림창 추가
- 예정: 신규 홈 화면 적용
- 솔리드 커넥션 서버
- Sentry 설정
- SQL PS
- 피곤해서 SQL 문제 풀이. 문법부터 조금씩 공부해나가자…
- 결과에 문자열 추가하려면 CONCAT
SELECT CONCAT(MAX(F.LENGTH), "cm") AS MAX_LENGTH
- 반올림 하려면 ROUND(value, int) 이때 int 가 2라면 소수점 2자리까지 보임(3자리에서 반올림)
- null인 값을 특정값으로 처리하려면 ISNULL이나 COALSCE. COALSCE는 여러값을 한번에 처리 가능.
SELECT ROUND(AVG(COALESCE(F.LENGTH, 10)), 2) AS AVERAGE_LENGTH