[내일배움캠프 본캠프] 2일 차 TIL - SQL, JdbcTemplate, IoC, DI, Bean

2026. 2. 11. 17:47·내배캠

2일 차 TIL

오늘은 스프링 입문 강의 메모장 프로젝트 CRUD 파트인 1-17부터
IoC와 Bean 파트인 2-5까지 수강했다.
데이터를 저장하는 방법들이 어떤 흐름으로 발전해 왔는지에 대해서 순서대로 설명해 준다고 느꼈다.

스프링 입문 1강

DB사용 전)

데이터를 세션단위로 저장할 수 있었다. 서버를 재시작하면 데이터가 소멸한다.
- Map<Long,Memo> 사용해서 HashMap 구현체에 저장

 

DB 사용 후)
Mysql을 사용해서 DB를 영구적으로 관리한다.

1. JdbcTemplate 으로 데이터 저장하기

쿼리문을 작성해서 JdbcTemplate에 넘겨줘서 실행할 수 있다.
이때 Jdbc는 데이터베이스에는 여러 종류가 있는데
백엔드 서버(Spring boot)에서 각 DB별로 작성해야 하는 코드형식이 다르다.

커넥션을 연결하는 방법
SQL을 전달하는 방법
결과를 응답하는 방법 등

그래서 사용하는 DB를 바구면 작성했던 코드들을 전부 수정해야 한다.


하지만 Jdbc 를 통해 각 DB를 기준으로 코드를 작성하는 것이 아닌
개발자는 표준화된 JDBC에 맞춰서 코드를 작성하면 돼서
DB의 종류에 구애받지 않을 수 있다.


ex) JDBC 도입으로 Mysql -> PostgreSQL 유연한 DB 변경 가능

2. JPA로 데이터 저장하기

-> ORM을 통해 쿼리문을 직접 작성하지 않고 데이터를 생성/관리할 수 있다.

Map객체에 데이터를 저장하면?
- 서버를 껏다 켜면 없어진다.
하지만 DB에 저장하면?
- 데이터를 영구적으로 보관할 수 있다.

JPA는 ORM의 표준 명세로써 애플리케이션 서버와 JDBC 사이에서 동작된다.

애플리케이션 <= JPA => JDBC

JPA를 구현한 것중 사실상 표준으로 사용되는 것이 바로 Hibernate이다.
사실상 표준이라는 말은 기업간 경쟁으로 시장에서 결정되는 비 공식적 표준을 뜻한다.

스프링 입문 2강

이전에는 직접 JdbcTemplate를 생성하고 리포지토리와 서비스 클래스에 주입하는 방식이었다면

 

3 Layer Architecture를 도입해서
컨트롤러의 요청 수신/응답, 비즈니스 로직(사용자의 요구사항을 처리), DB CRUD 작업을 분리할 수 있었다.

3 Layer Architecture


또한 각 클래스를 Bean으로 등록해 관리하여
이미 있는 객체(Bean)를 파라미터로 넘겨받아 사용함으로써
객체의 중복 생성을 막을 수 있었다.

 

다시말해 의존성 주입(DI)을 통한 제어의 역전(IoC)으로
객체의 중복 생성을 해결한 것이다.

DI는 Gof의 디자인 패턴
IoC는 객체지향의 SOLID 원칙에서 나왔다.

즉 DI패턴을 사용하여 IoC 설계 원칙을 구현할 수 있다.
강하게 결홥된 클래스는 interface 없이 필요한 것을 직접 만들어서 사용한다.

public class Consumer {

    void eat() {
        Chicken chicken = new Chicken();
        chicken.eat();
    }

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

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

- "치킨"외에 다른 음식을 먹으려면 eat() 메서드 자체를 수정해야 함.


하지만 inteface 다형성의 원리를 사용하여 구현한다면?

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("피자를 먹는다.");
    }
}

- eat 메서드는 그대로 두고 구현체를 생성하거나 수정하면 된다.

제어의 역전(IoC)는 Consumer가 직접 Food를 만들어서 먹는 것과 달리
Food를 Consumer에게 전달해 주는 것을 말한다.

Consumer -> Food
Food -> Consumer

 

기존의 메모장 프로젝트 서비스 코드

public class MemoService {

    private final JdbcTemplate jdbcTemplate;

    public MemoService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public MemoResponseDto createMemo(MemoRequestDto requestDto) {
        // DB 저장
        MemoRepository memoRepository = new MemoRepository(jdbcTemplate); // 객체 생성
				...
    }

    public List<MemoResponseDto> getMemos() {
        // DB 조회
        MemoRepository memoRepository = new MemoRepository(jdbcTemplate); // 객체 생성
        ...
    }

    public Long updateMemo(Long id, MemoRequestDto requestDto) {
        MemoRepository memoRepository = new MemoRepository(jdbcTemplate); // 객체 생성
        ...
    }

    public Long deleteMemo(Long id) {
        MemoRepository memoRepository = new MemoRepository(jdbcTemplate); // 객체 생성
        ...
    }
}

- 서비스(Consumer)가 리포지토리(Food)를 직접 만들어서 사용함 -> 객체 중복 생성 문제 발생


왜냐하면 리포지토리에게 파라미터로 JdbcTemplate로 넘겨줘야 하기 때문

 

IoC를 적용한 서비스 코드

public class MemoService {
   
    // 멤버 변수 선언
    private final MemoRepository memoRepository;

    // 생성자: MemoService(JdbcTemplate jdbcTemplate)가 생성될 때 호출됨
    public MemoService(JdbcTemplate jdbcTemplate) {
        this.memoRepository = new MemoRepository(jdbcTemplate); // 멤버 변수 생성
    }
    
   public MemoResponseDto createMemo(MemoRequestDto requestDto) {
        // RequestDto -> Entity
        Memo memo = new Memo(requestDto);

        // DB 저장
        Memo saveMemo = memoRepository.save(requestDto);

        // Entity -> ResponseDto
        MemoResponseDto memoResponseDto = new MemoResponseDto(saveMemo);

        return memoResponseDto;
    }
	...
}

 

- 리포지토리(Food)를 서비스(Consumer)에게 전달함 -> 객체 중복 생성 해결

 

강한 결합 상태의 메모장 프로젝트에서 제어의 흐름은 Controller ⇒ Service ⇒ Repository
하지만 DI 즉, 의존성 주입을 통해 제어의 흐름을 Repository ⇒ Service ⇒ Controller로 역전함으로써
효율적인 코드로 바뀌었습니다.

 

JdbcTemplate를 각 레이어에서 생성자로 한 번만 주입받기에
객체 중복 생성을 해결할 수 있다.

@Bean

근데 이 의존성을 주입받으려면 일단 해당 객체가 생성되어야 한다.
이를 Bean으로 객체를 등록하고, 스프링이 관리해줌으로써
개발자가 따로 new 키워드를 통해 생성하지 않아도 주입할 수 있다.

 

컨트롤러 - 서비스 - 리포지토리는 각각
@Controller - @Service - @Repository 어노테이션을 붙여서 Bean으로 등록할 수 있다.

에디터에서 커피콩 모양으로 Bean 등록유무를 확인할 수 있다.

Bean은 @ComponentScan으로 스프링이 등록해 준다.

의존성은 @Autowired를 통해 주입할 수 있지만
생성자가 1개인 경우 Spring 4.3 버전부터 생략가능하다.
아니면 @RequiredArgsConstruct를 사용해서 자동생성할 수도 있다.

 

수동으로 스프링에 등록된 Bean을 가져와서 의존성을 주입할 수도 있다.
ApplicationContext 객체를 사용하는 방법이다.

@Component
public class MemoService {

    private final MemoRepository memoRepository;

    public MemoService(ApplicationContext context) {
        // 1.'Bean' 이름으로 가져오기
        MemoRepository memoRepository = (MemoRepository) context.getBean("memoRepository");

        // 2.'Bean' 클래스 형식으로 가져오기
        // MemoRepository memoRepository = context.getBean(MemoRepository.class);

        this.memoRepository = memoRepository;
    }

		...		
}

에디더 우측에서 등록된 Bean을 확인이 가능하다.

Bean의 작명은 객체의 첫 글자만 소문자로 바꿔서 등록된다.
ex) MemoRepository -> memoRepository

'내배캠' 카테고리의 다른 글

[내일배움캠프 본캠프] 4일 차 TIL Bean 수동 등록, 쿠키/세션  (0) 2026.02.14
[내일배움캠프 본캠프] 3일 차 TIL 영속성 컨텍스트  (0) 2026.02.12
[내일배움캠프 본캠프] 1일 차 TIL 상품-주문 미니프로젝트 피드백  (0) 2026.02.10
[내일배움캠프 사전캠프] 3일 차 TIL Jackson  (0) 2026.02.06
[내일배움캠프 사전캠프] 2일 차 TIL 상품-주문 미니프로젝트  (0) 2026.02.05
'내배캠' 카테고리의 다른 글
  • [내일배움캠프 본캠프] 4일 차 TIL Bean 수동 등록, 쿠키/세션
  • [내일배움캠프 본캠프] 3일 차 TIL 영속성 컨텍스트
  • [내일배움캠프 본캠프] 1일 차 TIL 상품-주문 미니프로젝트 피드백
  • [내일배움캠프 사전캠프] 3일 차 TIL Jackson
MvA
MvA
백엔드 개발자 김재현입니다. 주로 공부하면서 느낀점을 기록합니다.
  • MvA
    Man vs Ai
    MvA
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • Java (6)
      • Python (8)
        • 딥러닝 (1)
        • 머신러닝 (7)
      • JavaScript (2)
      • 내배캠 (60)
      • 개인 프로젝트 (11)
      • 책 후기 (5)
      • 기타 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    딥러닝
    배포
    아키텍처
    내일배움캠프
    머신러닝
    Riot API
    TiL
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
MvA
[내일배움캠프 본캠프] 2일 차 TIL - SQL, JdbcTemplate, IoC, DI, Bean
상단으로

티스토리툴바