내일배움캠프 #18 #Spring 4일차

김한준 Hanjun Kim·2023년 11월 3일
0

내일배움캠프

목록 보기
18/70
post-thumbnail

위에 태그에 TIL을 제외하고는 오늘 배운 것들로 채워넣으면, 나중에 편할 것 같다고 생각해서 이렇게 해 놓으려고 한다.

어제 심화반 줌에서 물어본 질문인데

튜터님의 무기

DB (정형 데이터 : 엑셀 -> MySQL)
(비정형 데이터 : 시계열 데이터 -> NoSQL)
-> >>그런 매커니즘을 말로 표현할 수 있었고, 실험을 많이 해봐서 사람들이 모르는 셋팅을 잘했음<<

Spring을 극도로
Web CS를 극도로
코테를 극도로
다양한 걸 만들어 본 사람

등등이 자기의 "무기"이다

무기를 만들자..

DB 연결하는방법

  • build.gradle 에 MySQL 추가
  • 오른쪽에 코끼리(gradle) 위에 치즈모양 : DB
    '+' 버튼 -> DataSource -> MySQL -> User:root / Password:*** 입력 후 OK

깃허브 subtree 쓰면 파일들이 다 합쳐지는건 좋지만 커밋이 하나로 합쳐진다
-> 브랜치를 다 따로 파서 올리면?
https://santokki.tistory.com/24
이분 블로그 따라했음!


학습 정리

3 Layer Architecture

  • 한 코드에 클래스가 너무 길면 안좋다. 분리하자
    서버에서 처리 과정이 대부분 비슷함(Controller, Service, Repository = 3계층)
    Controller : Dispatcher Servlet 역할 담당
    Service : 비즈니스 로직, 요청 구현 역할 담당
    Repository : DB 역할 담당

역할 분리하기

  • MemoService, MemoRepository
    다른 클래스의 메서드를 호출하려면, 그 클래스의 객체를 만듦(인스턴스화, new 한다는 뜻)
    컨트롤러 메서드 이름과 서비스 이름을 일치시키면 -> 가독성 굿

Controller의 비즈니스 로직들을 Service를 만들어서 분리하는것,
Repository 기능 또한 Service에서 분리
변환, 전달, 확인 등의 과정만 남기고, 하위 기능들은 모두 Service -> Repository 순으로 분리
거름망? 원심분리기 같은?
공용 메서드 (findById 같은) 들은 맨 아래로 모음 -> 가독성 굿

-> 약간 내가 취약한 부분!!

IoC(제어의 역전), DI(의존성 주입)

  • 김볶밥 맛있게 만드는 방법 = 설계 원칙
    김볶밥 레시피 = 디자인 패턴

  • 의존성 : 말 그대로 의존성
    다리와 목발, 치킨과 소비자 같은 관계
    ex)
    소비자 클래스에서 Chicken chicken = new Chicken(); 하면
    치킨만 먹을수 있는데, 다른 거 먹으려면 계속 수정해야 한다.
    이런 강한 의존성을 느슨하게 하기 위해선
    자바의 interface를 활용해서 Food 인터페이스 객체를 만들면 느슨해짐!

public class Consumer {

    void eat(Food food) {
        food.eat();
    }

    public static void main(String[] args) {
        Consumer consumer = new Consumer();
        consumer.eat(new Chicken());
        consumer.eat(new Pizza());
    }
}

interface Food {
    void eat();
}

class Chicken implements Food{
    @Override
    public void eat() {
        System.out.println("치킨을 먹는다.");
    }
}

class Pizza implements Food{
    @Override
    public void eat() {
        System.out.println("피자를 먹는다.");
    }
}

consumer.eat(new Chicken()); <--- 바로 객체를 넣는 이 부분, 다형성의 원리!!


  • 주입 : 필요로 하는 객체를 요청한 객체한테 전달하는 과정
    필드에 직접 | 메서드를 통해 | 생성자를 통해 3가지 방법이 있다
    ex) 생성자를 통한 방법
public class Consumer {

    Food food;

    public Consumer(Food food) {
        this.food = food;
    }

    void eat() {
        this.food.eat();
    }

    public static void main(String[] args) {
        Consumer consumer = new Consumer(new Chicken());
        consumer.eat();

        consumer = new Consumer(new Pizza());
        consumer.eat();
    }
}

interface Food {
    void eat();
}

class Chicken implements Food{
    @Override
    public void eat() {
        System.out.println("치킨을 먹는다.");
    }
}

class Pizza implements Food{
    @Override
    public void eat() {
        System.out.println("피자를 먹는다.");
    }
}
  • 제어의 역전
    강한 의존성에서는 원래는 소비자가 치킨을 직접 만들어서 먹었는데,
    약한 의존성에서는 만들어진 음식을 제공받아서 먹음(주입)
    -> 유연성 효율성 굿!
    --> DI를 통해 IoC를 이루어 낸 것!

메모장 프로젝트의 IoC & DI

  • 메모장 프로젝트에서 보면, MemoService가 MemoRepository를 '직접' 만들고 있다
    = 제어의 흐름 : MemoController -> MemoService -> MemoRepository

(전)

문제점 해결하려면? 미리 만들어진 걸 전달!
1. 각 객체에 대한 생성은 1번
2. 생성된 객체를 재사용
3. 생성자 주입을 통해 필요로 하는곳에 전달!

= 제어의 흐름 :  MemoController <- MemoService <- MemoRepository

제어의 역전!

(후)

  • 근데 이미 만들어진 음식을 주입해줘야하는데 누가 어디서 만듬? 메인도 아닌데
    : 다음 강의에

IoC Container와 Bean

  • DI를 하기 위해선 객체 생성이 먼저
    Spring이 해주고 있다
    Bean : Spring이 관리하는 객체
    Container : Bean 컨테이너
    -> 클래스를 Bean 객체로 등록해야 함 : @Component

  • 메인에서 ComponentScan을 한다
    생성자가 1개면 생략이 되지만, 여러개면 @Autowired 붙여야 한다

  • 객체의 불변성을 지켜주기 위해 생성자로 주입을 하고 있었음(final 쓸려고)
    메서드로 주입하려면 @Autowired 붙여야 함
    필드로 주입하는방법도 @Autowired 붙여야 함. private도 되지만, 불안정하므로 지양

  • Lombok으로 할 수 있음. @RequiredArgsConstructor
    final을 생성자로 가져갑니다. 필드에 달아주면 됩니다

  • @Autowired 적용 조건
    Spring에서 관리받는 Bean 클래스에서만 가능(당연)

  • 수동 주입(x)

    public MemoService(ApplicationContext context) {
        // 1. 'Bean' 이름으로 가져오기 ( 난 안됌)
        MemoRepository memoRepository = (MemoRepository)context.getBean("memoRepository");
        this.memoRepository = memoRepository;
        
        // 2. 'Bean' 클래스 형식으로 가져오기
        MemoRepository memoRepository = context.getBean(MemoRepository.class);
        this.memoRepository = memoRepository;
    }
  • 3 Layer Component
    @RestController : DispatcherServlet이 내부적으로 찾아서 처리 / @Service / @Repository

JPA

  • ORM : 객체와 DB를 매핑. SQL 작업을 줄여주기 위해 등장

  • JPA : Java ORM 표준 기술
    JPA는 hibernate 를 씀
    hibernate : SQL 자동 생성!

Entity

  • JPA에 의해서 관리되고 있는 Class. 객체(여기선 Java에서 만듬)

  • persistence.xml 에서 hibernate를 사용하고 있다
    ID를 AutoIncrease 하고 싶다면? Memo - @Id 아래 @GeneratedValue(strategy = GenerationType.IDENTITY) 추가

  1. 테이블이 없는 상태에서 정보로 테이블을 만들때
  2. 이미 테이블은 만들어져 있고 테이블을 Entity랑 매핑할 때
    이 두 가지 고려

영속성 컨텍스트

  • 영속성 : Persistance, 영속성,지속성
    Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간

  • EntityManager : 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위함
    개발자들은 EntityManager를 통해 Entity를 조작 가능
    EntityManager는 EntityManagerFactory를 통해 생성

  • EntityManagerFactory : 만들기 위해서는 DB에 대한 정보를 전달해야 함
    META-INF - persistence.xml 파일을 만들어 정보를 넣어두면 된다 (Persistence.createEntity),(

ex)

// setUp 부분
EntityManagerFactory emf;
    EntityManager em;

    @BeforeEach
    void setUp() {
        emf = Persistence.createEntityManagerFactory("memo");
        em = emf.createEntityManager();
    }

Transaction

  • 트랜잭션 : DB 데이터들의 무결성과 정합성을 유지하기 위한 논리적 개념
    모든 SQL이 성공하면 반영하지만, 하나라도 실패하면 되돌려버린다

약간 Git같은 느낌? 마지막에 COMMIT 하지 않으면 반영이 되지 않는다!

JPA의 트랜잭션

  • 영속성 컨텍스트에 Entity 객체들을 저장했다고 해서 DB에 바로 반영되진 않는다
    트랜잭션의 개념을 가져와서, 지연 저장소에 가지고 있다가 Commit -> DB로 반영이 된다

! Entity에서 Setter를 사용할 때 주의 !

  • 영속성 컨텍스트들 안에서 PK로 Entity를 식별(identify)한다
    쿼리 중 values (? ? ?) 했던것.. jdbcTemplete 이였지

  • EntityManager에서 EntityTransaction을 가져올 수 있다
    et.begin()을 통해 트랜잭션 시작 / et.commit()을 통해 커밋 / et.close()로 종료까지

영속성 컨텍스트의 기능

  • 1차 캐시 : 우리가 저장하는 Entity 객체들이 1차 캐시, 즉 1차 저장소에 저장된다
    em.persist(객체) : 1차 캐시에 저장

  • 캐시 저장소는 Map 자료구조 형태로 되어있다
    key = Id, value = 해당 Entity 클래스의 객체

  • 데이터베이스 조회 횟수를 줄인다.
    em.find 할 때 마다 계속 select하는게 아니라, 1차 캐시에 중복이 있으니 그걸 사용하는 시스템?

  • 객체 동일성 보장!
    원래 객체 2개 생성해서 같다고 하면 틀리다
    but
    1차 캐시에 있는걸 받아온것이기 때문에 같다고 뜸!

profile
개발이 하고싶은 개발지망생

0개의 댓글