inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 스터디 클럽 1기] BE 2주차 회고록

miiro
1

두 번째 발자국


자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]를 수강하고

인프런 워밍업 클럽에 참여하여 쓰는 두 번째 회고록입니다.

학습 내용


static이 아닌 코드를 사용하려면 인스턴스화를 해야합니다.

하지만, 학습에서 진행했던 UserController는 jdbcTemplate를 의존하여 사용하고 있습니다.

이를 가능케 하는 것은 @RestController 어노테이션으로 의해 의존이 가능해지고 해당 클래스를 스프링 빈으로 등록시킵니다.

 

스프링 빈

서버가 시작되면, 스프링 서버 내부에 거대한 컨테이너를 만듭니다.

해당 컨테이너 안에는 클래스가 들어가게 되고, 다양한 정보(이름, 타입) 도 함께 들어가고, 인스턴스화도 이루어집니다.

서버가 시작되면 코드의 구현 순서에 대해 살펴보겠습니다.

  1. 스프링 컨테이너(즉, 클래스 저장소)가 시작됩니다.

  2. 기본적으로 생성되어있는 스프링 빈들이 등록됩니다.

  3. 사용자가 설정한 스프링 빈이 등록됩니다.

  4. 필요한 의존성이 자동으로 설정이 됩니다.

 

여기서 스프링 컨테이너를 사용하는 이유를 살펴보면 2가지의 스프링 프레임워크의 특성 때문입니다.

첫 번째는 제어의 역전(IOC) 이다. 말 그대로 메서드나 객체의 호출 작업을 개발자가 결정하는 것이 아닌, 외부(스프링 컨테이너)에서 결정되는 것을 의미입니다. 객체의 의존성을 역전시켜 객체간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 해서 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있도록 도와줍니다.

두 번째는 의존성 주입(DI) 로 객체를 직접 생성하는 것이 아닌 외부에서 생성할 후 주입시키는 방식을 의미한다.

이를 통해 모듈 간의 결합도가 낮아지고 유연성을 높일 수 있습니다.

 

 

스프링 빈으로 등록하는 방법

여기서 중점적으로 사용하는 어노테이션에 대해 살펴보겠습니다.

 

@Configuration

  1. 클래스에 붙이는 어노테이션

  2. @Bean을 사용할 때 함께 사용

  3. 외부 라이브러리, 프레임워크에서 만든 클래스를 등록할 때 사용한다.

@Bean

  1. 메서드에 붙이는 어노테이션

  2. 메서드에서 반환되는 객체를 스프링 빈에 등록한다.

  3. 외부 라이브러리, 프레임워크에서 만든 클래스를 등록할 때 사용한다.

@Service, @Repository

@Component

@Component 사용

  1. 컨트롤러, 서비스, 레포지토리 X

  2. 개발자가 직접 작성한 클래스를 스프링 빈으로 등록 시에 사용되기도 한다.

 

스프링 빈 주입 방법

  1. 생성자를 활용하여 주입하는 방법

  2. setter@Autowired를 사용하는 방법

  3. 필드에 직접 @Autowired를 사용하는 방법

 

JPA(Java Persistence API)

ORM(Object-Relational Mapping)

Hibernate

 

JPA 어노테이션

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

 

@Column(nullable = false, length = 20, name = "name")
private String name;

 

 

트랜잭션(Transaction)

 

트랜잭션 명령어

  1. start transaction; : 트랜잭션 시작하기

  2. commit; : 트랜잭션 정상 종료(SQL 반영)

  3. rollback; : 트랜잭션 실패 처리(SQL 미반영)

     

     

     

트랜잭션 적용 방법

@Transactional
public void saveUser(UserCreateRequest request) {
  userRepository.save(new User(request.getName(), request.getAge()));
}
@Transactional(readOnly = true)
public List<UserResponse> getUsers() {
  return userRepository.findAll().stream()
      .map(UserResponse::new)
      .collect(Collectors.toList());
}

 

주의사항

 

영속성 컨텍스트

특징

  1. 변경 감지(Dirty Check)

    1. 영속성 컨텍스트 안에 불러와진 Entity는 명시적으로 save 하지 않더라도, 변경을 감지해 자동으로 저장된다.

@Transactional
public void updateUser(UserUpdateRequest request) {
  User user = userRepository.findById(request.getId())
      .orElseThrow(IllegalArgumentException::new);

  user.updateName(user.getName());
}
  1. 쓰기 지연

    1. DB의 insert/update/delete SQL문을 바로 날리는 것이 아닌, 트랜잭션이 commit될때 모아서 1번만 날린다.

  2. 1차 캐싱

    1. ID를 기준으로 Entity를 기억한다.

    2. 캐싱된 객체는 완전히 동일하다.(객체 주소도 같다)

 

JPA 연관관계

연관관계의 주인 효과

@Transactional
public void savePerson() {
  Person person = personRepotiory.save(new Person());
  Address address = addressRepotiory.save(new Address());
  person.setAddress(address);
}

 

연관 관계의 주의점

@Transactional
public void savePerson() {
  Person person = personRepotiory.save(new Person());
  Address address = addressRepotiory.save(new Address ());
  person.setAddress(address);
  System.out.println(address.getPerson); //null 반환
}
public void setAddress(Address address) {
  this.address = address;
  this.address.setPerson(this);
}

 

다대일,일대다관계

다대다관계(N : M 관계)

cascade 옵션

orphanRemoval 옵션

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserLoanHistory> userLoanHistories = new ArrayList<>();

 

연관관계의 장점

  1. 각자의 역할에 집중하게 된다.

  2. 새로운 개발자가 코드를 읽을 때 이해하기 쉬워진다.

  3. 테스트 코드 작성이 쉬워진다.

연관관계 사용 시 주의 사항

 

과제 내용


Day 4

Day2에서 진행했던 GET API와 POST API를 구현했었는데, 그 당시에는 database를 사용하지 않은 방법으로 과제에서 주어진 조건에 맞게 답을 출력했었습니다. 이번 과제에서는 DB를 활용하여 정보를 저장하고, 수정할 수 있는 로직을 구현해야했습니다.

Layer를 분리해서 진행을 할 수 있지만, 간단하게 문제의 답만 도출하기 위해서 Controller Class에 구현을 진행했었습니다.

그렇기 때문에 Spring Data JPA가 아닌 JDBCTemplate를 활용하여 진행했습니다. JPA를 통한 DB 로직을 구현하는 것만 주구장창 했어서, 직접 쿼리문을 작성해서 진행하는 JDBCTemplate를 사용하는 방법에 대해 알 수 있었던 거 같습니다.

📋 4일차 미션 : GET API와 POST API 구현

 

Day 5

클린 코드는 코드를 아름답게 만드는 것이 아닌 코드의 질을 향상 시키는 데 중요하다는 것을 알았습니다.

클린 코드를 구현하기 위해서 명확하고 간결하게 코드를 구현하여 버그를 줄이고, 그로 인한 개발 속도를 향상시킬 수 있습니다.

또한, 잘 작성된 코드는 시간이 흘러도 이해하기 쉽기에, 유지 보수가 간편합니다. 이로 인해 개발자로서 팀 프로젝트를 진행할 시에

팀 커뮤니케이션을 원활하게 진행할 수 있도록 도움을 줄 수 있다는 것을 알게 되었습니다.

📋 5일차 미션 : 클린 코드 구현

 

 

회고


스프링 프레임워크의 핵심 개념인 제어의 역전(IOC)과 의존성 주입(DI)을 통해 더 나은 코드 작성과 유지 보수의 용이섬에 대해 알게 되었습니다. 또한 어노테이션들을 활용하여 클래스를 스프링 빈으로 등록하고, 스프링 컨테이너가 이를 관리함으로써, 필요한 의존성을 자동으로 설정할 수 있다는 사실을 배웠습니다. JPA를 통한 데이터의 영속성 관리와 ORM을 통한 객체와 DB의 매핑에 대해 이론적으로 정립할 수 있는 계기되었던 거 같습니다.

서비스를 구성하는 데 가장 중요한 @Transactional 어노테이션을 사용하여 데이터의 일관성을 유지하는 방법을 쉽게 공부하면서 더티 체크, 쓰기 지연 등 특성에 대해 알 수 있었던 거 같습니다.

객체와 DB를 효과적으로 설계할 수 있도록 연관관계를 설계하는 방법을 배움으로써 사용할 때의 주의사항과 성능 문제를 방지하기 위한 전략에 대해 알게 되면서 이를 통해 효과적이고 용이한 애플리케이션 개발을 할 수 있는 토대를 마련할 수 있었던 거 같습니다.

 

 

백엔드 인프런워밍업스터디클럽 2주차 회고록

답변 0