1주차 워밍업 발자국
웹서비스 구성요소클라이언트서버DB 주소창 입력시 통신 과정 1. 도메인을 DNS 서버를 통해서 ip주소로 받아온다.2. ip로 요청한다. 필요한 데이터를 같이 전달한다.3. 서버에서 작업을 처리 + DB crud4. DB가 결과 데이터 반환.5. 서버가 클라이언트를 통해 작업 수행결과를 응답한다. 웹 FW개발을 편리하게 만들어주는 도구. 프로그래밍 언어 : 삽으로 건물 짓기FW : 포크레인으로 건물 짓기. 프레임워크 vs 라이브러리제어의 흐름이 차이가 있다.FW가 어느정도 개발자에게 구조를 강제하는 IOC(제어의 역전)이 있다면라이브러리는 필요한 기능만 호출해서 사용할 수 있으니 개발자에게 제어권이 있다. Spring FW MVC패턴SW 아키텍쳐 디자인 패턴중 하나.요청 처리, 데이터, 화면의 역할을 분리해놓았다. Model : 데이터 담기. controller에서 model에 데이터를 넣어주고 view에서 꺼내간다.view : 사용자에게 보여지는 화면. model에서 데이터를 꺼내온다.controller : 요청을 받아 비즈니스 로직이 수행이 되면 응답을 전달. 응답 결과 데이터를 model에 넣는다. 레이어드 아키텍쳐MVC의 컨트롤러와 별개로 생각하자.계층별 분리를 하는게 재사용, 확장성, 협업시 유리하다.presentationbusinessdata access DI 스프링 Bean스프링에서 관리되는 인스턴스. 스프링에서 Bean으로 클래스를 지정하면 스프링컨테이너가 주체가 되서 직접 객체의 생명주기를 관리한다. 이게 IOC(제어의 역전). 의존성 주입(DI)는 클래스내에서 다른 객체를 사용할때 내부에서 만드는게 아니라 외부에서 주입받아 사용하는 방식. Bean 주입방식생성자수정자(Autowired)field생성자를 제일 권장한다.1. 수정자를 썼을 경우 런타임시 호출해서 의존성이 바뀔 수 있는 위험이 있다.2. 순환참조(Bean이 서로를 의존하는 것)시 런타임시 에러가 발생하는 경우를 막을 수 있다.3. 의존하는 Bean 누락시 컴파일 오류가 발생해서 런타임전 체크가 가능하다. HTTP와 REST APIHTTP네트워크 통신시 통신 규약. 요청Start Line : HTTP 메서드, URL, HTTP 버전header: 컨텐츠 길이, 유형, 브라우저 정보body: 실질적인 데이터. 보통 json 응답Start Line : HTTP 버전, 상태코드, 상태 메세지header, body 요청 메서드 GET서버 자원 조회 의미. read 작업GET을 쓰면 일부 HTTP 라이브러리에서는 Body에 데이터를 못담는 경우가 있어서 쿼리 파라미터를 주로 사용한다. POST create 작업 요청용. PUT, PATCH update 작업 DELETEdelete 작업 요청 상태코드200 : 정상처리300 : 리다이렉션. 주소입력시 다른 주소로 전송된다.400 : 클라이언트측 문제500 : 서버측 오류. REST APIHTTP 통신시 어플리케이션 기능을 정의하는 컨벤션. 핵심URL로 자원을 표현해서 어떤 자원에 대한 요청인지 이해할 수 있게 한다.CRUD에 부합하는 HTTP 메서드를 사용하자.HATEOAS 준수 : 응답에 링크를 포함해서 클라이언트가 다음에 할 행동을 가이드한다. 약간 행위를 HTTP 메서드를 활용하고 url을 좀더 간소화하는 느낌이다. 클라이언트에서 서버로 데이터 전달 방법Query Parameter쿼리스트링. @RequestParam 어노테이션으로 간편하게 가져온다.URL끝에 ?로 시작하고 파라미터별로 &로 구분한다.GET에서 주로 사용.HTTP Request Body@RequestBody어노테이션으로 가져온다.Path Variable경로 변수. URL에 접근하고자 하는 자원의 식별자. @PathVariable로 가져온다. 패키지 구조 DB 정의여러사람이 공유하며 사용할 목적으로 통합 관리하는 데이터의 집합 DBMS데이터 집합 관리 응용 프로그램.DBMS별 차이점 및 목적에 적합한 DBMS 선택이 필요하다. 관계형 DB행과 열로 이루어진 표로 저장. 이걸 테이블이라고 한다.행은 레코드라고 부른다. 기본키(Primary key)유일성 : 컬럼의 데이터 조합이 중복되면 안된다.최소성 : 최소한의 컬럼 조합을 사용해야 한다. 후보키 : pk가 될 수 있는 키들. 1대다 관계 테이블.테이블을 하나 더 만든다. 서비스 중 DB 변경은 어렵다. 처음부터 확장을 고려한 설계가 필요하다. RDBMS오라클유료이나 안정성mysql오라클 소유PostgreSQL오픈소스. 플러그인 확장성 좋음.비관계형 DB NoSQL MongoDB비정형적 데이터 저장RedisKey value 스토어캐시용 JPA자바 ORM 기술 표준 쿼리 직접 작성 과정이 생략되서 생산성 향상DBMS 의존성을 좀 낮출수 있음. 학습곡선 필요. 성능 약화나 의도치않은 쿼리가 나갈 수 있다.복잡한 쿼리는 한계가 있다. 트랜잭션여러 데이터 작업을 하나로 묶어주는 논리적인 단위이다. A통장에서 B통장으로 계좌이체를 한다고 하면 1. A에서 잔액 차감2. B에서 잔액 증가2가지가 필요하다.둘중 하나만 실행되면 안되므로 둘다 묶어서 성공 or 모두 실패 하도록 보장하는 것이다. 커밋트랜잭션으로 묶인 작업을 DB에 영구히 반영하는 작업이다.rollback트랜잭션으로 묶인 모든 작업을 원상 복구한다. 영속성 컨텍스트 테이블 설계 환경설정 H2 DBDBeaverDocker Git분산버전 관리 시스템. 프로젝트에 필요한 상수 관리자바코드에 직접 넣으면 수정시 매우 번거롭다. 매번 여러 값을 바꿔줘야 한다. profile로 세팅을 분기할 수 있다 @MappedSuperClassJPA에서 상속을 위한 엔티티 공통 매핑 정의시 사용한다. 중복 코드를 제거하고 공통 속성만 상속하도록 할 수 있다. @Id GenerationType : PK 생성전략 정하기TABLE : pk생성용 테이블을 따로 만듬. 성능적 손해가 있어서 별로.SEQUENCE : DB의 시퀀스 기능. 순서대로 번호. 오라클, PostgreSQL, DB2, H2에서 사용IDENTITY 기본키 생성을 DB에 위임. MySQL, PostgreSQL, SQL Server, DB2 등에서 사용.AUTO jpa가 알아서. mysql은 table을 사용한다. 공통으로 사용할 필드들 상속 받기 위해서 사용@MappedSuperclass // 상속받는 클래스가 테이블에 매핑 abstract class BaseEnitity 간단하게 엔티티 생성@Entity class Achievement : BaseEnitity() { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "achievement_id") // id를 안쓰는 이유는 achive2개뭍이는게 별로라서 var id: Long? = null } 엔티티별로 리포지토리 생성interface AchievementRepository : JpaRepository 리포지토리의 엔티티와 id의 타입을 제네릭 안에 받는다. 커밋 전에 모든 클래스 선택하고 CTRL + ALT+ L 하면 간편하게 정리 및 컨벤션 가능 @CreatedDate@LastModifiedDate엔티티 초기화시생성자로 초기화하는 방식 선택SkillType.valueOfenum 값 관련 string을 넣으면 그값에 맞는 enum을 리턴해준다.@Column(name = "skill_type") @Enumerated(value = EnumType.STRING) var type : SkillType = SkillType.valueOf(type) 다른 db의 사용을 생각한다면 컬럼의 명칭을 예약어를 피해서 정해주는 것이 좋다.컬럼의 명칭을 예약어로 사용하면 문법의 오류가 발생할 수도 있다.@Enumerated 자료형이 enum타입일떄 사용가능. 항상 타입을 STRING으로 지정해주는 것이좋다.ORDINAL : enum이 선언된 순서대로 넣는다.입력순서에 따라 들어가므로 직관적 파악이 어렵.누군가가 순서를 바꾼다면 정합성이 깨질 수 있음.STRING :enum의 이름대로 넣는다.연관관계 매핑eagerLoding을 지양하라고 얘기하고 있다.+ 즉시로딩시 N+1이 발생한다고 애기하시는데이부분은 좀 다시 생각해봐야 하지 않을까 싶다.@OneToMany(targetEntity = ExperienceDetail::class, fetch = FetchType.LAZY, cascade = [CascadeType.ALL]) @JoinColumn(name = "experience_id") var details: MutableList = mutableListOf()영속성 컨텍스트에 들어가거나 나올때 자식도 같이 적용하도록 하는것이cascade 옵션 @OneToMany(mappedBy = "project") var skills : MutableList = mutableListOf()양방향 연관관계를 쓸 때 사용했다.https://spoqa.github.io/2022/08/16/kotlin-jpa-entity.html회고 조금은 부랴부랴 듣는 감이 없지 않아 있다.그래도 전체적으로 훑고 가는 느낌이라 나쁘지는 않았다.미리 조금씩 듣는것도 좋을 것 같다. 미션 해결과정아직까지는 큰 문제는 없다.다만 추후 미니 프로젝트 진행시 되도록이면 연관관계를 안쓰고 싶긴하다.join으로 해결하면 로딩 관련 N+!, 데카르트곱등을 피할 수있고, jpa의 자체적인 문제에서 오는불필요한 쿼리를 보내지 않아도 되기 때문이다.