728x90

스프링에서 DB에 접근하는 방법에 대해 공부해보자.

 

DB는 H2를 사용하며 다운로드를 받고 실행 한 후 테이블을 생성한다.

drop table if exists member CASCADE;
create table student
(
        id   bigint generated by default as identity,
        name varchar(255),
        primary key (id)
);

이렇게 student 테이블을 생성을 한다.

 

이제 스프링으로 돌아가서 jdbc에 대한 설정을 해준다.

build.gradle에 dependencies에서

implementation 'org.springframework.boot:spring-boot-start-jdbc'
runtimeOnly 'com.h2database:h2'

를 추가해 jdbc, h2 데이터베이스 관련 라이브러리를 추가한다.

 

동기화를 해주고

resources/application.properties에서

spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasoure.username=sa

를 추가해준다.

동기화가 완료되면 빨간 줄이 드지 않을거다.

 

Jdbc 리포지토리 구현

Jdbc로 리포지토리를 구현해보려 했으나...

너무 어렵고 요즘은 쓰지 않기 때문에 여기에 코드를 적지는 않고 실행과 테스트만 해보도록 하겠다.

 

Service에서 사용하던 리포지토리를 memory에서 jdbc로 옮긴다는 것만 알고 있으면...

스프링을 껐다가 켜도 DB가 살아있다면 데이터가 유지되는 것을 볼 수 있다.

 

바로 테스트를 작성해보자.

package spring_practice.spring_practice.service;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import spring_practice.spring_practice.domain.Member;
import spring_practice.spring_practice.repository.MemberRepository;

@SpringBootTest
@Transactional
class MemberServiceDBTest {

    @Autowired
    MemberService memberService;
    @Autowired
    MemberRepository memberRepository;

    @Test
    public void join() throws Exception{
        //given
        Member member = new Member();
        member.setName("seungkyu");

        //when
        Long saveId = memberService.join(member);

        //then
        Member findMember = memberRepository.findById(saveId).get();
        Assertions.assertEquals(member.getName(), findMember.getName());
    }
}

DB를 사용할 때는 AfterEach를 사용하는 것이 아니라 @Transactional을 사용하면 테스트 후에 DB를 테스트 전으로 돌려준다.

 

AOP

모든 메서드에서 핵심은 아니지만 공통적으로 들어가는 사항이 있다. ex) 시간 측정

 

이 로직을 메서드 안에 넣어버리면 핵심 비즈니스의 로직과 섞여서 유지보수가 어려워 공통 관심 사항과 핵심 관심 사항으로 분리한다.

package spring_practice.spring_practice.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TimeTraceAop {

    @Around("execution(* spring_practice.spring_practice..*(..))")
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{
        long start = System.currentTimeMillis();
        System.out.println("START: " + joinPoint.toString());
        try{
            return joinPoint.proceed();
        }finally{
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");
        }
    }
}

'백엔드 > 스프링' 카테고리의 다른 글

스프링 7일차  (0) 2023.02.07
스프링 6일차  (0) 2023.02.06
스프링 5일차  (0) 2023.02.04
스프링 3일차  (0) 2023.02.01
스프링 2일차  (0) 2023.01.18

+ Recent posts