📢 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 와의 통신을 최대한 줄이고 싶어서 이러한 방식을 선택했다.
유연성, 확장성에 초점을 맞춰 설계하고자 했다.
- 현재 NCBT 프로젝트는 NCA, NCP 문제만 서비스할 계획이지만 추후 NCE 문제가 추가될 것을 고려하여 과목 및 과목별 문제 테이블을 분리했다.(관계형 데이터베이스에는 ‘상속’ 이라는 개념이 없지만 그래도 Java 개발자에게 익숙한 개념으로 설명하자면 subject 테이블이 부모 테이블, subject_question 이 자식 테이블이 된다.)
유지보수의 관점에서 중복 없이 간결하게 테이블을 구성하고자 했다.
- DB에 남길 데이터는 유저 정보와 북마크, 문제 오류 신고, 틀린 문제 데이터, 게임 관련 데이터이다. 이 중에서 subject, subject_question 테이블을 공통으로 사용하는 데이터들이 있어서 (중복을 최소화하기 위해) 자식 테이블인 subject_question 테이블에 is_wrong, is_bookmark 열을 추가했다.
자, 이제 개발을 시작해보자 !
🔖 참고문서