Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/gradlew text eol=lf
*.bat text eol=crlf
*.jar binary
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
220 changes: 146 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,146 @@
# :leaves: Spring_Boot D

DGU-UMC 9기 Spring Boot 스터디 D조

## 💻 Member

| 애나 | 루크 | 미로 | 누리 |
| :-----------------------------------: | :-----------------------------------: | :-----------------------------------: | :-----------------------------------: |
| [김민선](https://github.com/sunnyanna0) | [김도훈](https://github.com/DOHOON0127) | [이시은](https://github.com/miro-oss) | [정준영](https://github.com/cokanuri) |

## 📁 디렉토리 구조

- src 디렉토리를 실제 작업을 진행하는 Spring Boot의 src와 일치시켜 주세요.
- 미션 및 실습, 주차를 정확히 구분하기 위해 아래의 commit 규칙을 ‼️반드시‼️ 준수하여 commit 후 push 해 주세요.

```bash
├─.github
│ └─PULL_REQUEST_TEMPLATE
│ └─ISSUE_TEMPLATE
├─README.md
└─src
├─main
└─test
└─...

```

## 🎨 commit 규칙

- 해당 commit이 미션에 관한 것일 경우: "mission/#해당 주차"

```
Ex) 1주차 미션 수행 후
mission/#01
```

- 해당 commit이 실습에 관한 것일 경우: "practice/#해당 주차"

```
Ex) 2주차 실습 수행 후
practice/#02
```

- 해당 주차에 미션이나 실습이 없는 경우, 있는 주차에만 수행하시면 됩니다.

## 🌳 branch 규칙

```bash
├─main
├─angela/main
│ └─angela/#1
```

1. `닉네임/main 브랜치`가 기본 브랜치로 pr 보낼 때 root 브랜치(main 브랜치)가 아닌 닉네임/main 브랜치로 올립니다.
2. 매주 워크북, 실습, 그리고 미션은 각자의 닉네임/main 브랜치를 base 브랜치로 삼아 `닉네임/이슈번호 브랜치`를 생성하여 관련 파일을 업로드합니다.
3. 모든 팀원들의 approve를 받으면, pr을 머지하고 해당 pr을 생성한 브랜치(닉네임/이슈번호 브랜치)는 삭제합니다. approve와 merge는 스터디 진행 중에 이루어집니다.

## 🔖 커밋 컨벤션

| Message | 설명 |
| :------: | :-------------------- |
| mission | 미션 수행 |
| practice | 실습 수행 |
| keyword | 키워드 정리 |
| workbook | 워크북 정리 |
| fix | 버그 수정 |
| docs | 문서 수정 |
| comment | 주석 추가 및 변경 |
| test | 테스트 코드 추가 |
| rename | 파일 혹은 폴더명 수정 |
| remove | 파일 혹은 폴더 삭제 |
| chore | 기타 변경사항 |
속성별 제약조건 정리

## member

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| member_id | BIGINT(20) | PK, NOT NULL | 회원 고유 ID |
| name | VARCHAR(50) | NOT NULL | 회원 이름 |
| nickname | VARCHAR(50) | NOT NULL | 닉네임 |
| gender | VARCHAR(10) | NOT NULL | 성별 |
| birth | DATE | NOT NULL | 생년월일 |
| address | VARCHAR(255) | NOT NULL | 주소 |
| status | VARCHAR(15) | NOT NULL | 회원 상태 (정상/탈퇴 등) |
| withdrawal_date | DATETIME | NULL | 탈퇴일 |
| email | VARCHAR(255) | NULL | 이메일 |
| phone | VARCHAR(20) | NULL | 전화번호 |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |
| point | INT(20) | NOT NULL | 보유 포인트 |

---

## food

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| category_id | BIGINT(20) | PK, NOT NULL | 음식 카테고리 ID |
| category_name | VARCHAR(50) | NOT NULL | 음식 카테고리명 |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## member_food

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| id | BIGINT(20) | PK, NOT NULL | 고유 ID |
| member_id | BIGINT(20) | FK → member.member_id | 회원 ID |
| category_id | BIGINT(20) | FK → food.category_id | 음식 카테고리 ID |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## mission

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| mission_id | BIGINT(20) | PK, NOT NULL | 미션 고유 ID |
| store_id | BIGINT(20) | FK → store.store_id | 가게 ID |
| mission_condition | VARCHAR(50) | NOT NULL | 미션 조건 |
| mission_deadline | DATE | NOT NULL | 미션 기한 |
| point | INT(20) | NOT NULL | 포인트 |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## member_mission

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| id | BIGINT(20) | PK, NOT NULL | 고유 ID |
| member_id | BIGINT(20) | FK → member.member_id | 회원 ID |
| mission_id | BIGINT(20) | FK → mission.mission_id | 미션 ID |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## store

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| store_id | BIGINT(20) | PK, NOT NULL | 가게 ID |
| region_id | BIGINT(20) | FK → region.region_id | 지역 ID |
| name | VARCHAR(50) | NOT NULL | 가게 이름 |
| address | VARCHAR(255) | NOT NULL | 가게 주소 |
| rating | DECIMAL(2,1) | NOT NULL | 평점 |
| status | VARCHAR(50) | NOT NULL | 영업 상태 |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## region

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| region_id | BIGINT(20) | PK, NOT NULL | 지역 고유 ID |
| name | VARCHAR(50) | NOT NULL | 지역명 |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## review

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| review_id | BIGINT(20) | PK, NOT NULL | 리뷰 고유 ID |
| store_id | BIGINT(20) | FK → store.store_id | 가게 ID |
| member_id | BIGINT(20) | FK → member.member_id | 작성자 ID |
| content | VARCHAR(255) | NOT NULL | 리뷰 내용 |
| rating | DECIMAL(2,1) | NOT NULL | 평점 |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## review_reply

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| reply_id | BIGINT(20) | PK, NOT NULL | 댓글 ID |
| review_id | BIGINT(20) | FK → review.review_id | 리뷰 ID |
| content | VARCHAR(255) | NOT NULL | 댓글 내용 |
| created_at | DATETIME(6) | NOT NULL | 생성일 |
| updated_at | DATETIME(6) | NOT NULL | 수정일 |

---

## review_photo

| 컬럼명 | 데이터 타입 | 제약조건 | 설명 |
|--------|--------------|-----------|------|
| photo_id | BIGINT(20) | PK, NOT NULL | 사진 ID |
| review_id | BIGINT(20) | FK → review.review_id | 리뷰 ID |
| photo_url | VARCHAR(255) | NULL | 사진 URL |

---

# 연관관계 매핑

| 관계 | 매핑 방향 | 관계 유형
|------|------------|------------|
| Member – Review | 양방향 | 1:N |
| Member – MemberFood | 양방향 | 1:N |
| Member – MemberMission | 단방향 | 1:N |
| Mission – MemberMission | 양방향 | 1:N |
| Mission – Store | 양방향 | N:1 |
| Store – Region | 양방향 | N:1 |
| Review – ReviewReply | 양방향 | 1:1 |
| Review – ReviewPhoto | 양방향 | 1:N |
| Food – MemberFood | 단방향 | 1:N |
78 changes: 78 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.6'
id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
description = 'Demo project for Spring Boot'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'com.h2database:h2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

// QueryDSL - 공식 버전 사용
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'

// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.13'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.8.13'

// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'

// Jwt
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
implementation 'org.springframework.boot:spring-boot-configuration-processor'
}

tasks.named('test') {
useJUnitPlatform()
}

// QueryDSL 설정
def generated = layout.buildDirectory.dir('generated/querydsl').get().asFile

sourceSets {
main.java.srcDirs += [generated]
}

tasks.withType(JavaCompile) {
options.getGeneratedSourceOutputDirectory().set(file(generated))
}

clean {
delete file(generated)
}
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading