[인프런워밍업스터디_BE_0기] 3주차 정리!
섹션 5. 책 요구사항 구현하기
[섹션 목표]
1. 책 생성, 대출, 반납 API를 온전히 개발하며 지금까지 다루었던 모든 개념을 실습해본다.2. 객체지향적으로 설계하기 위한 연관관계를 이해하고, 연관관계의 다양한 옵션에 대해 이해한다.
3. JPA에서 연관관계를 매핑하는 방법을 이해하고, 연관관계를 사용해 개발할 때와 사용하지 않고 개발할 때의 차이점을 이해한다.
객체지향적 설계를 위한 연관관계를 이해하고, 연관관계의 다양한 옵션에 대해 알아보자
기존 UserLoanHistory를 다음과 같이 변경해주었다.
@Entity
public class UserLoanHistory {
// ..중략
@ManyToOne
private User user;
public UserLoanHistory(User user, String bookName) {
this.user = user;
this.bookName = bookName;
this.isReturn = false;
}
}
그리고 User도 다음과 같이 변경하였다.
@Entity
public class User {
// ...중략
@OneToMany(mappedBy = "user")
private List<UserLoanHistory> userLoanHistoryLists = new ArrayList<>();
// ...중략
}
이렇게 엔티티를 매핑해줄 때는 연관관계의 주인에 대해 꼭 알아야한다. 이 연관관계의 주인은 쉽게 생각하면 테이블을 보았을 때 누가 관계의 주도권을 가지고 있는지를 의미한다. 현재 user와 user_loan_history 테이블에서 user_loan_history는 user_id를 컬럼으로 가지고 있어 user를 알고 있지만 user는 user_loan_history를 알지 못한다. 즉 연관관계의 주인이 user_loan_history라는 것이다. 그래서 mappedBy = "user"라고 적음으로써 UserLoanHistory의 user 필드가 연관관계의 주인이라는 것을 JPA에게 알려주는 것이다!
이렇게 연관관계를 이어주고 나면 다음과 같은 어노테이션과 속성들을 사용할 수 있다.
@JoinColumn
: 연관관계의 주인이 활용할 수 있는 어노테이션으로 다른 테이블을 가리키는 필드의 이름이나 null 여부, 유일성 여부 등을 정해줄 수 있다.
cascade
옵션 : 객체가 저장되거나 삭제될 때 연결되어 있는 객체도 함께 저장되거나 삭제되는 기능
orphanRemoval
옵션 : 연결이 끊어지면 그 데이터를 삭제하는 옵션
그리고 지난 주에 알아보았던 영속성 컨텍스트의 능력중 4번째 능력도 이번 시간에 알아볼 수 있었다. 영속성 컨텍스트의 4번째 능력은 바로 지연 로딩
이다. 이번에 연관관계를 매핑해보았는데, User를 가져올 때마다 List<UserLoanHistory>를 가져온다면 어떨까? 사용하지도 않는데 쿼리를 쓸 데 없이 한 번 더 날리는 꼴이 될 것이다. 지연 로딩
은 List<UserLoanHistory>가 필요한 순간이 왔을 때 가져올 수 있도록 하는 기능이다!
연관관계를 사용해 개발할 때와 사용하지 않고 개발할 때의 차이점?
이러한 연관관계를 사용했을 때 좋은 점은 무엇일까? 이번 시간 연관관계를 활용하여 User와 UserLoanHistory가 서로 협업하게 되었다. 이로 인해 Service 코드가 간결해졌고, 우리의 비즈니스 로직이 도메인 계층으로 옮겨가게되었다! 이런 식으로 각 도메인과 계층이 자신의 역할에만 집중할 수 있게 되면 테스트 코드를 작성하기도 더욱 쉬워진다! 그리고 코드를 이해하기도 편해진다!
이렇게 좋은 연관관계지만 사용했을 때의 단점 또한 존재한다. 연관관계가 복잡하게 얽히게 되면 해당 시스템을 파악하기도 어려워지고, 서로 강하게 연결되어있기 때문에 한 곳을 수정하면 다른 곳까지 영향을 주게 된다. 그래서 언제 연관관계를 쓰고 언제 쓰지 않는 것이 좋을까?! 정답은 없지만 고려해보면 좋을 점은 '라이프 사이클'이다. 두 객체의 생성과 종료가 함께 이루어질 경우에 연관관계를 사용하는 것을 고려해볼만하다!
섹션 6. 생애 최초 배포 준비하기
[섹션 목표]
1. 배포가 무엇인지 이해하고, 배포를 하기 위해 어떤 준비를 해야 하는지 알아본다.2. 스프링 서버를 실행할 때 DB와 같은 설정들을 코드 변경 없이 제어할 수 있는 방법을 알아본다.
3. git과 github의 차이를 이해하고 git에 대한 기초적인 사용법을 알아본다.
4. AWS의 EC2가 무엇인지 이해하고, AWS를 통해 클라우드 컴퓨터를 빌려본다.
배포란 무엇일까?
지난 강의를 통해 만들어진 우리의 애플리케이션을 다른 사람들이 사용하게 하고 싶다면 어떻게 해야할까? 컴퓨터에 애플리케이션이 동작하기 위해 필요한 스프링, MySQL들을 설치하고 애플리케이션을 실행시킨 뒤 이 곳으로 접속하게 하면 될 것이다. 이러한 과정을 우리는 배포라고 한다!
스프링 서버를 실행할 때 DB와 같은 설정들을 코드 변경 없이 제어하는 방법
스프링 서버를 실행할 때 스프링은 profile을 확인하여 해당 profile의 설정을 적용한다! 따라서 다음과 같이 spring.config.activate.on-profile
을 통해 profile의 이름을 지정해주고, 해당 profile을 통해 실행하도록 하면 된다.
--- local 프로필
spring:
config:
activate:
on-profile: local
datasource:
url: "jdbc:h2:mem:library;MODE=MYSQL;NON_KEYWORDS=USER"
username: "sa"
password: ""
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
format_sql: true
dialect: org.hibernate.dialect.H2Dialect
h2:
console:
enabled: true
path: /h2-console
--- dev 프로필
spring:
config:
activate:
on-profile: dev
datasource:
url: "jdbc:mysql://localhost/library"
username: "root"
password: "1234"
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: none
properties:
hibernate:
show_sql: true
format_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect
git과 github의 차이점과 git을 사용하기 위한 간단한 명령어를 알아보자
git
은 코드를 쉽게 관리할 수 있도록 해주는 버전 관리 프로그램
이다. 그러면 github
는 무엇일까? github는 git으로 관리되는 코드가 저장되는 저장소이다. 그럼 git을 사용하기 위한 간단한 명령어에 대해 알아보자!
git init
: 프로젝트를 git이 관리하도록 한다.git remote add origin 주소
: 프로젝트의 git 저장소를 해당 주소로 설정한다.git add 폴더 혹은 파일 이름
: 해당 폴더 또는 파일을 저장소에 저장할 수 있도록 추가한다.git status
: 현재 관리 중인 파일들의 상태를 보여준다.git commit -m "메세지"
: 저장소에 저장할 때 표시할 메세지를 추가하고 저장소에 저장할 준비를 한다.git push
: 저장소에 저장한다.
AWS의 EC2란?
EC2란 Elastic Compute Cloud의 약자로 탄력적으로 원격 컴퓨터를 사용할 수 있다는 뜻이다. 즉, 필요할 때 컴퓨터를 빌렸다가 언제든지 컴퓨터를 반납하는 등 탄력적으로 원격 컴퓨터를 사용할 수 있다는 것이다.
이번 시간에는 AWS에 회원가입을 하여 원격 컴퓨터를 빌려보았다. 다음 시간에는 실제로 배포를 해보자!
섹션 7. 생애 최초 배포하기
[섹션 목표]
1. EC2에 접속하는 방법을 알아보고, EC2에 접속해 리눅스 명령어를 다뤄본다.2. 개발한 서버의 배포를 위해 환경 세팅을 리눅스에서 진행하고, 실제 배포를 진행한다.
3. foreground와 background의 차이를 이해하고 background 서버를 제어한다.
4. 도메인 이름을 사용해 사용자가 IP 대신 이름으로 접속할 수 있도록 한다.
EC2에 접속해보고 리눅스 명령어에 대해 알아보자
EC2에 접속하기 위해서는 다음 세 가지를 준비해야한다.
우리가 접속하려 하는 EC2의 IP 주소
키 페어 (pem 키)
접속하기 위한 프로그램
Windows - git CLI (git bash)
Mac - terminal
git CLI를 열어 다음 명령어를 통해 EC2에 접속해보자
-- 처음 ssh 접속할 때 사용할 명령어
chmod 400 경로/키페어이름.pem
ssh -i 경로/키페어이름.pem ec2-user@ip 주소
위 방법 외에 AWS 콘솔 환경에서 연결할 컴퓨터를 선택하고 연결 -> 인스턴스에 연결 -> 연결을 눌러 접속할 수도 있다.
이제 간단한 리눅스 명령어에 대해 알아보자
mkdir 폴더이름
: 폴더를 만드는 명령어
ls
: 현재 위치에서 폴더나 파일을 확인하는 명령어, -l 을 통해 조금 더 자세한 정보를 확인할 수 있다.
cd 폴더
: 폴더 안으로 들어가는 명령어
pwd
: 현재 위치를 확인하는 명령어
rmdir
: 피어있는 폴더를 제거하는 명령어
sudo yum update
: 관리자의 권한으로 설치되어 있는 여러 프로그램을 최신화한다.
sudo yum install 프로그램 이름
: 관리자의 권한으로 프로그램을 설치한다.
sudo systemctl status 프로그램
: 관리자의 권한으로 프로그램의 상태를 확인한다.
sudo systemctl restart 프로그램
: 관리자의 권한으로 프로그램을 재시작한다.
chmod
: 파일이나 폴더의 권한을 변경한다.
ctrl + c
: foreground로 실행중인 프로그램을 중단하는 신호
nohup [명령어] &
: 명령어를 background로 실행시킨다.
rm 파일명
: 파일을 제거하는 명령어
vi 파일명
: 리눅스 편집기인 vim을 사용하여 파일을 연다.
cat
: 파일에 있는 내용물을 모두 출력하는 명령어
tail
: 현재 파일의 끝 부분을 출력하는 명령어, -f 를 사용하여 끝 부분을 실시간으로 출력할 수 있다.
ps aux
: 현재 실행중인 프로그램 목록을 확인할 수 있다.
kill -9 프로그램 번호
: 해당 프로그램을 종료시킨다.
Gradle 관련 명령어도 정리하면 다음과 같다.
./gradlew build
: 프로젝트를 빌드한다.
./gradlew clean
: 현재 빌드된 결과물을 제거한다.
미니 프로젝트
시간 관계상 1단계까지 밖에 구현하지 못하였지만.. 스터디가 끝난 뒤에도 추가로 4단계까지 구현해보려고 한다!
미니프로젝트 : https://github.com/HyeongSeop-Kim/warming-up-study-assignment/tree/master/mini-project
3주차를 마치며
아쉬웠던 점
마지막 주까지 일/학습 병행의 어려움은 두고두고 아쉬움이 남는다...ㅠ 3주동안 나름의 해결을 위해 이 방법, 저 방법 동원해보았지만 해답을 찾지 못한 점이 너무 아쉽다.. 특히 시간이 흐를 수록 쌓이는 피로 덕분에 회사 업무에 지장을 주기도 하고, 이를 해결하기 위해 하루는 공부를 건너뛰기도 하는 등 아쉬움이 많았다.
칭찬할 점
그래도.. 모든 진도를 끝까지 따라간 점은 역시 칭찬할만 하지 않을까..!
보완할 점
스터디 이후에 혼자 공부할 때 어떤 방법으로 공부해야할 지 정리도 하고 생각해봐야겠다..!
댓글을 작성해보세요.