Skip to content

[현서호] 1주차 과제 #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions src/main/java/doit/jpastudy2/Jpastudy2Application.java
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
public class Jpastudy2Application {

public static void main(String[] args) {

SpringApplication.run(Jpastudy2Application.class, args);
}

21 changes: 13 additions & 8 deletions src/main/java/doit/jpastudy2/repository/Category.java
Original file line number Diff line number Diff line change
@@ -15,19 +15,24 @@
public class Category {

@Id // PK임을 나타낸다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 생성되는 값임을 나타낸다.
@Column(name = "category_id") // 컬럼명을 지정한다.
private Long id;
//@GeneratedValue(strategy = GenerationType.AUTO) // 자동 생성되는 값임을 나타낸다.
@Column(name = "exercise") // 컬럼명을 지정한다.
private String exercise;
Comment on lines 17 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우선 수고하셨습니다! 코드 보니 어떠한 어려움이 있으셨을지 예상이 가서 몇가지 정보를 공유해드리겠습니다.

  1. Entity에서 @id는 해당 필드가 PK값임을 의미합니다. 따라서 유일하게 작성될 수 있도록 수동으로 작성하지 않는 편이 좋습니다.
  2. 숫자형 타입의 필드에 @id와 @GeneratedValue(strategy=GenerationType.AUTO)를 함께 사용하게 되면, 데이터베이스 단에서 자동으로 유일한 PK 값을 할당합니다. ( MySQL의 경우 이전의 PK 값 + 1)
  3. String 타입의 @id 필드에는 @GeneratedValue(strategy=GenerationType.AUTO)를 사용할 수 없습니다. 데이터베이스 단에서 이 값을 자동으로 생성할 수 없기 때문입니다.

따라서 아래처럼 작성하는 편이 조금 더 보편적입니다.

Suggested change
@Id // PK임을 나타낸다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 생성되는 값임을 나타낸다.
@Column(name = "category_id") // 컬럼명을 지정한다.
private Long id;
//@GeneratedValue(strategy = GenerationType.AUTO) // 자동 생성되는 값임을 나타낸다.
@Column(name = "exercise") // 컬럼명을 지정한다.
private String exercise;
@Id // PK임을 나타낸다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 생성되는 값임을 나타낸다.
@Column(name = "exercise_id") // 컬럼명을 지정한다.
private Long id;


// @Column(name = "type")이 생략된 경우 필드명이 컬럼명이 된다. snake_case로 변환된다.
private String type;
private String time;

// @Column(name = "description")이 생략된 경우 필드명이 컬럼명이 된다.
private String description;
private String cORw;
Copy link
Member

@jjunhub jjunhub Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유산소 혹은 근력으로 표현하기 위해서 해당 필드를 사용하신 것 같습니다.
디테일하게 필드 작성하신 점 좋습니다!
추가로 다른 사람들도 보자마자 바로 알 수 있도록 이를 조금 더 이해하기 쉬운 이름으로 아래처럼 작성해주는 것이 어떨까 생각이 듭니다.

Suggested change
private String cORw;
private String exerciseType;



private String place;

@Builder // 빌더 패턴을 사용할 수 있게 한다.
public Category(String description, String type) {
this.description = description;
this.type = type;
public Category(String exercise, String time, String cORw, String place) {
this.exercise = exercise;
this.time = time;
this.cORw = cORw;
this.place = place;
}
}
35 changes: 35 additions & 0 deletions src/main/java/doit/jpastudy2/repository/Category1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package doit.jpastudy2.repository;

import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor
@Getter
public class Category1 {

@Id // PK임을 나타낸다.
//@GeneratedValue(strategy = GenerationType.AUTO) // 자동 생성되는 값임을 나타낸다.
@Column(name = "exercise") // 컬럼명을 지정한다.
private String exercise;

// @Column(name = "type")이 생략된 경우 필드명이 컬럼명이 된다. snake_case로 변환된다.
private String gold;

// @Column(name = "description")이 생략된 경우 필드명이 컬럼명이 된다.
private String silver;


private String bronze;

@Builder

public Category1(String exercise, String gold, String silver, String bronze) {
this.exercise = exercise;
this.gold = gold;
this.silver = silver;
this.bronze = bronze;
}
}
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@ public interface CategoryRepository extends JpaRepository<Category, Long> {
// find + [ ] + By + (조건)

// select * from Category
Category findByDescription(String description);
// Category findByDescription(String description);

// select * from Category where type = ? and description = ?
Category findByTypeAndDescription(String type, String description);
// Category findByTypeAndDescription(String type, String description);
}
Comment on lines 10 to 17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우선 클래스까지는 잘 생성해주셨습니다.
다만 이 쪽에서 JpaRepository를 사용하기 위해서는, JpaRepository<Entity Class 이름, 그 클래스의 PK 타입>으로 작성해야합니다. 현재까지 작성해주신 Entity는 String 타입이어서 아래와 같이 작성할 수 있습니다.

Suggested change
// find + [ ] + By + (조건)
// select * from Category
Category findByDescription(String description);
// Category findByDescription(String description);
// select * from Category where type = ? and description = ?
Category findByTypeAndDescription(String type, String description);
// Category findByTypeAndDescription(String type, String description);
}
public interface CategoryRepository extends JpaRepository<Category, String> {

17 changes: 17 additions & 0 deletions src/main/java/doit/jpastudy2/repository/CategoryRepository1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package doit.jpastudy2.repository;

import org.springframework.data.jpa.repository.JpaRepository;

public interface CategoryRepository1 extends JpaRepository<Category, Long> {

// 쿼리 메소드 패턴은 다음과 같다.
// [ ] = Optional
// ( ) = 조건
// find + [ ] + By + (조건)

// select * from Category1
// Category1 findByDescription(String description);

// select * from Category where type = ? and description = ?
// Category findByTypeAndDescription(String type, String description);
}
102 changes: 53 additions & 49 deletions src/test/java/doit/jpastudy2/repository/CategoryRepositoryTest.java
Original file line number Diff line number Diff line change
@@ -22,87 +22,91 @@ class CategoryRepositoryTest {
void test() {
// Given
Category category1 = Category.builder()
.type("양식")
.description("데이트")
.exercise("수영")
.time("30분")
.cORw("유산소")
.place("수영장")
.build();

Category category2 = Category.builder()
.type("한식")
.description("한국인의 정")
.exercise("탁구")
.time("30분")
.cORw("유산소")
.place("탁구장")
.build();

// When
categoryRepository.save(category1);
categoryRepository.save(category2);

// Then
List<Category> categories = categoryRepository.findAll();
Assertions.assertThat(categories).hasSize(2);
Assertions.assertThat(categories.get(0).getType()).isEqualTo("양식");
Assertions.assertThat(categories.get(0).getDescription()).isEqualTo("데이트");
}

@DisplayName("Description을 이용한 조회")
@Test
void findByDescription() {
// Given
Category category1 = Category.builder()
.type("양식")
.description("데이트")
Category category3 = Category.builder()
.exercise("볼링")
.time("20분")
.cORw("근력")
.place("볼링장")
.build();

Category category2 = Category.builder()
.type("한식")
.description("한국인의 정")
Category category4 = Category.builder()
.exercise("클라이밍")
.time("60분")
.cORw("근력")
.place("클라이밍장")
.build();

// When
categoryRepository.save(category1);
categoryRepository.save(category2);

// When
Category result1 = categoryRepository.findByDescription("철가방");
Category result2 = categoryRepository.findByDescription("데이트");
categoryRepository.save(category3);
categoryRepository.save(category4);

// Then
Assertions.assertThat(result1).isNull();
Assertions.assertThat(result2).isNotNull();
Assertions.assertThat(result2.getType()).isEqualTo("양식");
List<Category> categories = categoryRepository.findAll();
Assertions.assertThat(categories).hasSize(2);
Assertions.assertThat(categories.get(0).getPlace()).isEqualTo("탁구장");
Assertions.assertThat(categories.get(0).getCORw()).isEqualTo("근력");
}

@DisplayName("description과 type을 이용한 조회")
@DisplayName("유산소/근력을 이용한 조회")
@Test
void findByTypeAndDescription() {
void findByCORw() {
// Given
Category category1 = Category.builder()
.type("양식")
.description("데이트")
.exercise("수영")
.time("30분")
.cORw("유산소")
.place("수영장")
.build();

Category category2 = Category.builder()
.type("한식")
.description("한국인의 정")
.exercise("탁구")
.time("30분")
.cORw("유산소")
.place("탁구장")
.build();

Category category3 = Category.builder()
.type("중식")
.description("철가방")
.exercise("볼링")
.time("20분")
.cORw("근력")
.place("볼링장")
.build();

Category category4 = Category.builder()
.type("미식")
.description("축구ㅋㅋ")
.exercise("클라이밍")
.time("1시간")
.cORw("근력")
.place("클라이밍장")
.build();

categoryRepository.saveAll(List.of(category1, category2, category3, category4));
// When
categoryRepository.save(category1);
categoryRepository.save(category2);
categoryRepository.save(category3);
categoryRepository.save(category4);

// When
Category result1 = categoryRepository.findByTypeAndDescription("양식", "데이트");
Category result2 = categoryRepository.findByTypeAndDescription("중식", "데이트"); // null
Category result3 = categoryRepository.findByTypeAndDescription("미식", "축구ㅋㅋ");
Category result1 = categoryRepository.findByCORw("근력");
Category result2 = categoryRepository.findByCORw("유산소");

// Then
Assertions.assertThat(result1.getType()).isEqualTo("양식");
Assertions.assertThat(result2).isNull();
Assertions.assertThat(result3.getDescription()).isEqualTo("축구ㅋㅋ");
Assertions.assertThat(result1).isNull();
Assertions.assertThat(result2).isNotNull();
Assertions.assertThat(result1.getPlace()).isEqualTo("수영장");
Comment on lines 107 to +110
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검증하는 파트는 꼼꼼하게 잘 작성해주신 것 같습니다.
앞서 코멘트 달아두었던 내용들 반영해서 수정하신 뒤에, 다시 테스트 실행해보시면 좋을 것 같습니다!!

고생하셨습니다~

}
}