📢 NCBT 프로젝트는 ‘기획 - 분석 - 설계 - 구현 - 테스트 - 운영’ 이라는 프로그래밍의 라이프사이클을 지켜 진행했지만 추후 회고록을 돌아볼 때 ‘프로젝트 세팅’ 부분을 가장 많이 찾아볼 것 같아서 이 부분을 먼저 작성했다.

1️⃣ 프로젝트 세팅

< Back >

1. Build.gradle 의존성 추가

분류정보
기본- Spring Boot DevTools
- Lombok
- Spring Web
마이바티스- MyBatis Framework
- JDBC API
- MySQL Driver
시큐리티- Spring Security
- OAuth2 Client

2. application.yml

# DB 연결 정보
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ncbt
    username: "" #ID
    password: "" #PW

# 마이바티스 설정
mybatis:
  type-aliases-package: kr.bit.ncbt.domain
  mapper-locations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true

3. MyBatisConfig.class

@Configuration
public class MyBatisConfig {

// DataSource : 데이터베이스 연결을 제공하는 객체. yml 에서 설정한 DB 연결 정보가 자동으로 주입된다.
    @Autowired
    private DataSource dataSource;

// MyBatis에서 SQL 세션을 관리하는 sessionFactory 를 생성하는 객체. 데이터베이스와의 상호작용을 처리한다.
    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        return factoryBean.getObject();
    }
}

4. Mapper Interface

  • Mapper 는 스프링 빈으로 사용해도 되고 xml 파일을 따로 빼서 사용해도 된다.
  • 개인적으로 스프링 빈 어노테이션을 사용하는 것이 직관적이고 간편해서 빈으로 사용했다.
@Mapper
public interface TestMapper {
    @Select("SELECT * FROM user")
    List<User> testSelect();

    @Insert("INSERT user(email,nickname,password,is_admin,platform) " +
            "values (#{email}, #{nickname}, #{password}, #{is_admin}, #{platform})")
    int testInsert(User user);

}

5. JUnit Test

  • 1~4 까지 설정한 후 단위테스트로 마이바티스 연동 여부를 확인해줬다.
@SpringBootTest
public class TestMapperTest {

    @Autowired
    private TestMapper testMapper;

    @Test
    public void insertTest() {
        // given
        User user = new User();
        user.setEmail("test@email");
        user.setPassword("123456");
        user.setNickname("tester3");
        user.set_admin(false);
        user.setPlatform("normal");

        // when
        testMapper.testInsert(user);

        // then
        List<User> users = testMapper.testSelect();
        User userTest = users.get(users.size() - 1);
        Assertions.assertThat(userTest).isEqualTo(user);
    }
}

 

2️⃣ 요구사항 분석 및 ERD 설계

0. 요구사항 정리

  • 우선 우리 프로젝트의 기능 및 요구사항을 정리해보았다.
  • 회원은 가입, 로그인, 로그아웃이 가능하고, 원하는 문제를 북마크하거나 문제 오류를 신고할 수 있다.
  • 관리자는 관리자 페이지에서 회원 정보를 확인할 수 있고 회원 증감 추이를 일별, 월별로 확인할 수 있다. 또한 회원의 신고를 접수하여 문제를 수정하거나 삭제할 수 있다.
  • CBT 는 연습문제, 실전문제 풀기 기능이 있다.
  • 게임은 실전문제 풀이를 유저 간 1 vs 1 로 대결하여 즐길 수 있는 기능이다.
회원관리자CBT게임
회원 가입회원 관리연습문제 풀기1 vs 1 대결
로그인, 로그아웃회원 수 증감 추이 확인실전문제 풀기 
북마크문제 수정, 삭제 확인  
문제 오류 신고   

 

1. 초기 설계 240901

  • 위 요구사항을 바탕으로 작성한 ERD 테이블이다.
  • 특이사항으로, NCBT 프로젝트는 시험문제 데이터를 리액트 로컬스토리지에서 관리하기로 했다. 문항 수가 많지 않아 가능한 방식으로, 성능 최적화를 위해 DB 와의 통신을 최대한 줄이고 싶어서 이러한 방식을 선택했다.

스크린샷 2024-11-27 오후 4 13 51

  • 유연성, 확장성에 초점을 맞춰 설계하고자 했다.

    • 현재 NCBT 프로젝트는 NCA, NCP 문제만 서비스할 계획이지만 추후 NCE 문제가 추가될 것을 고려하여 과목 및 과목별 문제 테이블을 분리했다.(관계형 데이터베이스에는 ‘상속’ 이라는 개념이 없지만 그래도 Java 개발자에게 익숙한 개념으로 설명하자면 subject 테이블이 부모 테이블, subject_question 이 자식 테이블이 된다.)
  • 유지보수의 관점에서 중복 없이 간결하게 테이블을 구성하고자 했다.

    • DB에 남길 데이터는 유저 정보와 북마크, 문제 오류 신고, 틀린 문제 데이터, 게임 관련 데이터이다. 이 중에서 subject, subject_question 테이블을 공통으로 사용하는 데이터들이 있어서 (중복을 최소화하기 위해) 자식 테이블인 subject_question 테이블에 is_wrong, is_bookmark 열을 추가했다.

자, 이제 개발을 시작해보자 !

🔖 참고문서

스프링 부트 기초

스프링 부트와 마이바티스 연동-1

스프링 부트와 마이바티스 연동-2

DB 설계는 어떻게 해야 할까?