스터디일지/PROJECT

[Java Spring] 입문 2 주차 강의 - PART 1

똥쟁이핑크 2023. 8. 29. 22:53

Layer Architecture

https://miro.medium.com/v2/resize:fit:1358/1*g0htFSEnplHtdXYcZG3qZQ.gif

  • 하나의 controller에서 모든 API를 처리하면 코드 이해하기도 힘들고 변경을 할 때 문제가 발생할 수 있다.
  • 그래서 Spring 에서는 3개로 분리했는데 Controller, Service, Repository다.

 

  • Controller
    • Client에게서 오는 요청을 받는다.
    • 요청을 받으면 Service에 전달한다. - request 데이터가 있으면 같이 전달하게 된다.
    • Service에서 처리한 결과를 Client에게 응답한다.
  • Service
    • 강의에서는 실세라 했다.
    • 비즈니스 로직을 처리하고 코드의 양이 점점 많아진다.
    • DB에 저장하거나 조회가 필요하면 Repository에 전달한다.
  • Repositoty
    • DB를 관리한다.
    • DB CURD 작업을 처리한다.
    • CRUD = Create, Read, Update, Delete

 

IoC와 DI 이해하기

IoC는 제어의 역전을 뜻하고 DI는 의존성 주입이다.

2가지는 객체지향의 SOLID원칙과 GoF의 디자인 패턴과 같은 설계원칙 및 디자인 패턴이다.

구분을 하면 IoC는 설계 원칙이고 DI는 디자인 패턴이라고 구분할 수 있다.

Spring에서 두 가지를 사용해서 좋은 코드를 작성할 수 있게 해 준다.

DI 패턴을 사용해서 IoC 설계 원칙을 구현한다라고 이해하면 좋다.

 

  • IoC - 설계원칙
    • 요리로 따지면 재료, 비율, 재료의 순서 등을 이야기할 수 있다.
    • 제어의 역전 - 프로그램의 흐름이 뒤바뀜.
    • 일반적으로 개발자가 객체를 직접 제어해야만 하지만 제어의 역전이 일어나면 Spring에서는 객체에 대한 제어권이 컨테이너로 역전된다. - Bean(객체)을 등록하기만 하면 된다.
    • Spring 에서 Controller → Service → Repository 순으로 흐름이 진행되었다면 제어의 역전이 일어나면 Repository → Service → Controller 순으로 흐름이 바뀐다.
  • DI - 디자인 패턴
    • 요리로 치면 볶고, 풍미를 내는 과정이라 할 수 있다.
    • 의존성 주입
    • 의존성이 강하면 코드를 수정해야 할 때 관련된 코드를 전부 수정해야 한다. 그래서 의존성을 낮춰야 한다. Interface 다형성의 원리를 사용해서 구현하면 의존성이 낮아진다. = 결합을 약하게 한다, 약한 의존성
    • 강한 결합을 해결하려면 각 객체에 대한 생성은 1번만 하고 모든 곳에서 재사용하고 생성자 주입을 사용해서 필요로 하는 객체에 해당 객체를 주입하는 방법이다.
    • 주입은 여러 가지 방법을 사용해서 필요로 하는 객체를 해당 객체에 전달하는 것이다.  주입하는 방법은 필드에 직접적으로 주입하거나 메서드를 사용하거나 생성자를 사용해서 주입할 수 있다.

스파르타 코딩 클럽 - 강한 결합
스파르타 코딩 클럽 - 약한 결합

  • 좋은 코드
    • 논리가 간단해야 한다.
    • 중복제거 및 표현이 명확해야 한다.
    • 코드를 처음 보는 사람도 쉽게 이해하고 수정할 수 있어야 한다.
    • 의존성을 최소화해야 한다.
    • 기능을 추가할 때 크게 구조의 변경이 없어야 한다.

 

IoC Container와 Bean

IoC Container는 Bean을 모아둔 컨테이너고 Bean은 Spring 이 관리하는 객체를 말한다.

모든 객체가 다 Bean이 되는 것이 아니고 등록을 해줘야 한다.

Bean으로 등록 하고자 하는 클래스 위에 @Component를 적어준다.

Spring 서버가 동작할 때 IoC Container에 Bean을 저장한다.

등록하면 옆에 콩처럼 생긴 아이콘이 뜬다. Spring IoC에서 관리하는 Bean클래스라는 표시다.

Bean을 사용하려면 사용하고자 하는 메서드 위에 @Autowired를 적어주는데

Spring 4.3 버전부터는 생략이 가능해졌고 생략이 가능할 때는 생성자가 1개 일 때만 생략이 가능하다.

2개 이상이면 써줘야 한다.

 

그런데 앞에서 3 Layer Architecture에서 이미 3개의 층으로 분리했고

각각 Controller, Service, Repository의 역할이 있기 때문에

@Component가 아니라 각각 @Controller, @Service, @Repository로 사용하는 것이 좋다

그 안에 @Component가 추가되어 있기 때문이다.

 

 

JPA CORE

  • JPA
    • DB를 다룰 때는 직접 쿼리를 짜서 테이블을 만들고 Application에 저장하고 JDBC를 이용해서 직접 실행한 후에 객체로 직접 만들어야 해서 SQL에 대한 의존성이 높았다.
    • 그래서 ORM = Object-Relational Mapping - 객체 관계 매핑이라 하며 SQL 작업을 줄여주는 기술이 나왔다. 많은 작업을 자동으로 처리해 준다.
    • JPA는 Java Persistence API로 자바 ORM 기술에 대한 표준 명세를 말한다.
    • JPA는 Application과 JDBC 사이에서 동작한다.
    • JPA를 사용하면 DB연결 과정 개발을 하지 않아도 자동으로 처리해 준다.
    • 객체를 통해 간접적으로 DB데이터를 다룰 수 있어서 매우 쉽게 작업처리를 할 수 있다.
  • Hibernate
    • JPA는 표준 명세라고 이야기했고 이것을 실제로 구현한 프레임 워크 중 사실상 표준이라고 말할 수 있는 게 하이버네이트다.
    • Spring Boot에서 기본적으로 Hibernate구현체를 사용한다.

 

Entity 이해하기

https://images.velog.io/images/agugu95/post/189b4d5e-002c-4e7c-a4fb-89f0dd60f435/image.png

  • JPA에서 관리되는 클래스 즉, 객체를 의미한다.
  • Entity 클래스는 DB의 테이블과 매핑되어 JPA에 의해 관리된다.
  • @ 을 써서 Entity 클래스를 지정할 수 있다.
  • @Entity
    • JPA가 관리할 수 있는 Entity클래스로 선언할 때 사용한다.
    • @Entity(name = "이름") Entity클래스 이름을 지정할 때 사용하고 Default는 클래스명이다.
    • JPA가 Entity클래스를 인스턴스화할 때 기본 생성자를 사용한다. 그래서 현재 Entity클래스에서 기본 생성자가 됐는지 확인해야 한다.
  • @Table
    • 매핑할 테이블을 지정할 때 사용한다.
    • @Table(name = "이름") 매핑할 테이블의 이름을 지정할 때 사용한다. Default는 Entity명이다.
  • @Column
    • @Column(name="이름") 필드와 매핑할 테이블의 컬럼을 지정할 때 사용한다. Default는 객체의 필드명이다.
    • @Column(nullable = false) 데이터의 null 값 허용 여부를 지정할 때 사용한다. Default는 true다
    • @Column(unique = true) 데이터의 중복 값 허용 여부를 지정할 때 사용한다. Dafault는 false다
    • @Column(length = 500) 데이터의 길이에 조건을 걸 때 사용한다. Default는 225다
  • @Id
    • 테이블의 기본 키를 지정할 때 사용한다.
    • 영속성 컨텍스트에서 Entity를 구분하고 관리할 때 사용하는 식별자 역할을 한다.
    • 식별자를 넣어주지 않고 저장하면 오류가 발생한다.
    • @Id 옵션만 설정하면 기본 키 값을 개발자가 직접 확인하고 넣어줘야 한다.
  • @GeneratedValue 
    • 이 옵션을 추가하면 기본 키 생성을 DB에 위임할 수 있다.
    • @GeneratedValue(strategy = GenerationType.IDENTITY)처럼 사용할 수 있다.

 

영속성 컨텍스트란?

https://user-images.githubusercontent.com/71188307/124583713-55bb6980-de8e-11eb-965c-2147e54d4dec.png

  • Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간이다. 
  • JPA는 영속성 컨텍스트에 Entity 객체를 저장하고 관리하면서 DB랑 소통한다.
  • 조작하기 위해서는 EntityManager가 필요하고 EntityManager를 사용해서 Entity를 조회, 수정, 삭제할 수 있다.
  • EntityManager를 생성하려면 EntityManagerFactory를 사용해서 생성할 수 있다.
  • EntityManagerFactory는 DB 하나에 하나만 생성되어 Application이 동작하는 동안 사용된다.

  • EntityManagerFactory사용하려면 빨간 네모칸 안에 있는 persistence.xml에 DB에 대한 정보를 담아 두면 사용가능 하다.
// 예시 코드
EntityManagerFactory emf = Persistence.createEntityManagerFactory("memo"); // 생성하기
EntityManager em = emf.createEntityManager(); // Manager생성하기
  • 영속성 컨텍스트는 내부적으로 캐시 저장소를 가지고 있고 Map 자료 구조 형태로 되어 있다.
  • Key는 식별자 값을 저장하고 Value는 Entity클래스의 객체를 저장한다.
  • 영속성 컨텍스트에서 저장하는 Entity객체들이 1차 캐시로 저장소에 저장된다. 1차 캐시를 사용하면 DB조회 횟수도 줄이고 객체 동일성도 보장할 수 있다.
  • flush() 메서드는 영속성 컨텍스트의 변경 내용들을 DB에 반영하는 역할을 한다.

 

 

JPA 트랜잭션

  • DB를 안전하게 관리하기 위해 생겨난 개념이다.
  • 여러 개의 SQL이 하나의 트랜잭션에 포함될 수 있는 것이 가장 큰 장점이라고 할 수 있다.
  • 영속석 컨텍스트에 Entity객체를 저장해도 바로 DB에 반영되지 않는다. 마지막에 한 번에 요청해서 저장하는데 JPA에서도 마찬가지다.
  • 이 개념을 적용하려면 EntityManager에서 EntityTransaction을 가져와서 적용할 수 있다.
// 예시 코드
EntityTransaction et = em.getTransaction(); // 호출하기
et.begin(); // 트랜잭션 시작하기
et.commit(); // 영구적으로 DB에 반영하는 하기
et.rollback(); // 오류 발생 시 모든 작업을 취소하고 이전 상태로 되돌리기

 

오늘까지 배운 내용을 이해한 대로 정리해 보았다. 

확실히 강의 보고 코드치고 따라가기 바빴는데 정리하니 이해되는 부분이 많았다.

 

 

 

 

참고한 사이트

https://velog.io/@damiano1027/Spring-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85-%EC%A0%9C%EC%96%B4%EC%9D%98-%EC%97%AD%EC%A0%84

 

[Spring] 의존성 주입, 제어의 역전

공부하며 작성한 내용이기 때문에 오류 사항이 있을 수 있습니다. 잘못된 부분은 피드백 부탁드립니다.Spring에서의 의존성 주입과 제어의 역전에 대해 알아본다. Spring에서의 의존성 주입이란 다

velog.io