Skip to content
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

박자스동터차 경주 2단계 #8

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
227e10f
[1단계 - 웹 자동차 경주] 박스터(한우석) 미션 제출합니다. (#49)
drunkenhw Apr 14, 2023
479dd33
refactor: domain에서 spring 의존성 제거
drunkenhw Apr 14, 2023
fa3f081
refactor: save all 메서드 batch update로 변경
drunkenhw Apr 14, 2023
11d31ed
refactor: 불필요한 어노테이션 변경
drunkenhw Apr 14, 2023
314f00d
test: controller 단위 테스트 추가
drunkenhw Apr 14, 2023
6a0e142
test: display name 추가
drunkenhw Apr 14, 2023
95f6855
refactor: db접근을 위한 entity 추가
drunkenhw Apr 15, 2023
ca7c8d6
feat: 객체 검증 기능 추가
drunkenhw Apr 15, 2023
06abb19
refactor: racing game test 가독성 좋게 수정
drunkenhw Apr 15, 2023
ce71dda
refactor: 출력 형식에 맞도록 수정
drunkenhw Apr 15, 2023
1e63c66
refactor: racing game 방식 변경
drunkenhw Apr 15, 2023
ce96d76
refactor: 승자를 구하는 로직 추가
drunkenhw Apr 15, 2023
6ba3533
feat: racing game을 조회하는 기능 추가
drunkenhw Apr 16, 2023
39d4e46
feat: racing game id로 car를 조회하는 기능 추가
drunkenhw Apr 16, 2023
1b31c3c
feat: 전체 결과를 조회하여 결과를 반환하는 기능 추가
drunkenhw Apr 17, 2023
c4a600c
feat: api 추가
drunkenhw Apr 17, 2023
35f4996
feat: 예외 처리 컨트롤러 추가
drunkenhw Apr 17, 2023
068f395
feat: 콘솔 게임 기능 추가
drunkenhw Apr 17, 2023
578e675
feat: In memory Dao 추가
drunkenhw Apr 21, 2023
06b0608
refactor: simpleJdbcInsert를 사용하도록 변경
drunkenhw Apr 21, 2023
e886c52
refactor: 최상위 예외를 잡는 메서드 추가
drunkenhw Apr 21, 2023
a5de3c2
refactor: 프론트에서 List로 반환하도록 변경
drunkenhw Apr 23, 2023
04bb0d8
refactor: service 클래스 분리
drunkenhw Apr 23, 2023
7fada27
refactor: rest api 응답 형식으로 변경
drunkenhw Apr 23, 2023
6fda343
feat: valid를 통한 검증 추가
drunkenhw Apr 23, 2023
f7d899e
refactor: 결과를 조회하는 서비스에 transactional 추가
drunkenhw Apr 23, 2023
3b99dd9
refactor: 예외 처리 문구 수정
drunkenhw Apr 23, 2023
9cf0152
refactor: trasactional 어노테이션 추가
drunkenhw Apr 23, 2023
dcf1b6d
refactor: racing game을 수행하는 클래스 추가
drunkenhw Apr 23, 2023
ea55c02
refactor: racing game console 서비스 클래스 제거
drunkenhw Apr 26, 2023
d46221c
refactor: racing game play 서비스 클래스 제거
drunkenhw Apr 26, 2023
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
17 changes: 10 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.9'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'java'
id 'org.springframework.boot' version '2.7.9'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

sourceCompatibility = '11'

repositories {
mavenCentral()
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
testImplementation 'io.rest-assured:rest-assured:4.4.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}
61 changes: 61 additions & 0 deletions src/main/java/racingcar/RacingCarConsoleApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package racingcar;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import racingcar.controller.RacingConsoleController;
import racingcar.dao.CarDao;
import racingcar.dao.RacingGameDao;
import racingcar.dao.entity.CarEntity;
import racingcar.dao.entity.RacingGameEntity;
import racingcar.service.RacingGameService;

public class RacingCarConsoleApplication {
public static void main(String[] args) {
RacingGameService racingGameService = new RacingGameService(new InnerCarDao(), new InnerRacingGameDao());
RacingConsoleController racingConsoleController = new RacingConsoleController(racingGameService);
racingConsoleController.run();
}

static class InnerCarDao implements CarDao {
private final Map<Long, CarEntity> database = new HashMap<>();
private Long key = 1L;

@Override
public void saveAll(List<CarEntity> racingCars) {
for (CarEntity racingCar : racingCars) {
database.put(key, racingCar);
key++;
}
}

@Override
public List<CarEntity> findByRacingGameId(Long id) {
return database.values().stream()
.filter(carEntity -> Objects.equals(carEntity.getGameId(), id))
.collect(Collectors.toList());
}
}

static class InnerRacingGameDao implements RacingGameDao {
private final Map<Long, RacingGameEntity> database = new HashMap<>();
private Long id = 1L;

@Override
public Long save(RacingGameEntity racingGameEntity) {
database.put(id, racingGameEntity);
id++;
return id - 1;
}

@Override
public List<RacingGameEntity> findAllByCreatedTimeAsc() {
return database.values()
.stream().sorted(Comparator.comparing(RacingGameEntity::getCreatedTime))
.collect(Collectors.toList());
}
}

Choose a reason for hiding this comment

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

웨 static class?

}
19 changes: 19 additions & 0 deletions src/main/java/racingcar/controller/ControllerAdvice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package racingcar.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ControllerAdvice {

@ExceptionHandler
public ResponseEntity<String> handleValidationExceptions(RuntimeException e) {
return ResponseEntity.internalServerError().body(e.getMessage());

Choose a reason for hiding this comment

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

e.getMessage()를 통해 runtimeException 같은거를 잡게 되면 너무 많은 정보가 돌아갈 수 있어서
"예상치 못한 어쩌구" 같은 메시지로 바꿔주는게 좋아보이는거?

}

@ExceptionHandler
public ResponseEntity<String> handleValidationExceptions(IllegalArgumentException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}

Choose a reason for hiding this comment

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

어떤 예외를 잡는건지 명시해주면 좋을 것 같아요
이렇게 해도 되나? 되면 말고

}
27 changes: 27 additions & 0 deletions src/main/java/racingcar/controller/RacingConsoleController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package racingcar.controller;

import racingcar.dto.RacingGameRequest;
import racingcar.dto.RacingGameResponse;
import racingcar.service.RacingGameService;
import racingcar.view.InputView;
import racingcar.view.OutputView;

public class RacingConsoleController {

private final RacingGameService racingGameService;

public RacingConsoleController(RacingGameService racingGameService) {
this.racingGameService = racingGameService;
}

public void run() {
String names = InputView.inputNames();
int count = InputView.inputTryCount();
RacingGameRequest racingGameRequest = new RacingGameRequest(names, count);

Choose a reason for hiding this comment

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

web 에서 사용되는 것 같은 request 나 response 가
console 에서 사용되는 것이 안좋아보이는데
네이밍 고민이나, service 에서 List<String> 같은거 받도록 바꿔보면 어때?


RacingGameResponse racingGameResponse = racingGameService.play(racingGameRequest);

OutputView.printRacing(racingGameResponse.getRacingCars());
OutputView.printWinners(racingGameResponse.getWinners());
}
}
32 changes: 32 additions & 0 deletions src/main/java/racingcar/controller/RacingGameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package racingcar.controller;

import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import racingcar.dto.RacingGameRequest;
import racingcar.dto.RacingGameResponse;
import racingcar.service.RacingGameService;

@RestController
public class RacingGameController {
private final RacingGameService racingGameService;

public RacingGameController(RacingGameService racingGameService) {
this.racingGameService = racingGameService;
}

@PostMapping("/plays")
public ResponseEntity<RacingGameResponse> play(@RequestBody RacingGameRequest racingGameRequest) {

Choose a reason for hiding this comment

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

@valid

어노테이션 써봐도 좋을듯

RacingGameResponse response = racingGameService.play(racingGameRequest);
return ResponseEntity.ok(response);

Choose a reason for hiding this comment

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

http code 201이 더 어울리긴 하네

}

@GetMapping("/plays")
public ResponseEntity<List<RacingGameResponse>> playHistory() {
List<RacingGameResponse> history = racingGameService.findHistory();
return ResponseEntity.ok(history);
}
}
11 changes: 11 additions & 0 deletions src/main/java/racingcar/dao/CarDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package racingcar.dao;

import java.util.List;
import racingcar.dao.entity.CarEntity;

public interface CarDao {

void saveAll(List<CarEntity> racingCars);

Choose a reason for hiding this comment

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

saveAll 이 void 이고, RacingGameDao 에서는 Long 이라서 통일성이 떨어지는 느낌
id를 반환할거면 다 똑같이 long 으로 적어줘
List<Long>


List<CarEntity> findByRacingGameId(Long id);
}
50 changes: 50 additions & 0 deletions src/main/java/racingcar/dao/CarJdbcDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package racingcar.dao;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import racingcar.dao.entity.CarEntity;

@Component
public class CarJdbcDao implements CarDao {

private final JdbcTemplate jdbcTemplate;

public CarJdbcDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Override
public void saveAll(List<CarEntity> racingCars) {
String sql = "INSERT INTO CAR (name, position, is_win, racing_game_id) VALUES (?, ?, ?, ?)";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
CarEntity carEntity = racingCars.get(i);
ps.setString(1, carEntity.getName());
ps.setInt(2, carEntity.getPosition());
ps.setBoolean(3, carEntity.isWin());
ps.setLong(4, carEntity.getGameId());
}

@Override
public int getBatchSize() {
return racingCars.size();
}
});

Choose a reason for hiding this comment

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

웨 않 simpleInsert?

Choose a reason for hiding this comment

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

해 봐두 줗울지두

}

@Override
public List<CarEntity> findByRacingGameId(Long racingGameId) {
return jdbcTemplate.query("SELECT * FROM car WHERE racing_game_id = " + racingGameId,
(resultSet, rowNum) -> new CarEntity(
resultSet.getString("name"),
resultSet.getInt("position"),
resultSet.getBoolean("is_win"),
racingGameId
));
}
}
11 changes: 11 additions & 0 deletions src/main/java/racingcar/dao/RacingGameDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package racingcar.dao;

import java.util.List;
import racingcar.dao.entity.RacingGameEntity;

public interface RacingGameDao {

Long save(RacingGameEntity racingGameEntity);

List<RacingGameEntity> findAllByCreatedTimeAsc();
}
46 changes: 46 additions & 0 deletions src/main/java/racingcar/dao/RacingGameJdbcDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package racingcar.dao;

import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Component;
import racingcar.dao.entity.RacingGameEntity;

@Component
public class RacingGameJdbcDao implements RacingGameDao {

private final JdbcTemplate jdbcTemplate;

public RacingGameJdbcDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Override
public Long save(RacingGameEntity racingGameEntity) {
String sql = "INSERT INTO racing_game (trial_count, created_at) VALUES (?,?)";

KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(con -> {
PreparedStatement preparedStatement = con.prepareStatement(sql, new String[]{"id"});
preparedStatement.setInt(1, racingGameEntity.getTrialCount());
preparedStatement.setTimestamp(2, Timestamp.valueOf(racingGameEntity.getCreatedTime()));

Choose a reason for hiding this comment

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

이렇게 하는거구나 안 써봐서 처음 알았네

return preparedStatement;
}, keyHolder);

return keyHolder.getKey().longValue();
}

@Override
public List<RacingGameEntity> findAllByCreatedTimeAsc() {
return jdbcTemplate.query(
"SELECT * FROM racing_game ORDER BY created_at DESC ",
(resultSet, rowNum) -> new RacingGameEntity(
resultSet.getLong("id"),
resultSet.getInt("trial_count"),
resultSet.getTimestamp("created_at").toLocalDateTime()

Choose a reason for hiding this comment

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

이거 좋은데요

));
}
}
32 changes: 32 additions & 0 deletions src/main/java/racingcar/dao/entity/CarEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package racingcar.dao.entity;

public class CarEntity {

Choose a reason for hiding this comment

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

Entity를 식별할 수 있는 식별자가 없는 것 같은데 의도하신걸까요? 🤔


private final String name;
private final int position;
private final boolean isWin;
private final Long gameId;

public CarEntity(String name, int position, boolean isWin, Long gameId) {
this.name = name;
this.position = position;
this.isWin = isWin;
this.gameId = gameId;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}

public boolean isWin() {
return isWin;
}

public Long getGameId() {
return gameId;
}
}
32 changes: 32 additions & 0 deletions src/main/java/racingcar/dao/entity/RacingGameEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package racingcar.dao.entity;

import java.time.LocalDateTime;

public class RacingGameEntity {

private final Long id;
private final int trialCount;
private final LocalDateTime createdTime;

public RacingGameEntity(Long id, int trialCount, LocalDateTime createdTime) {
this.id = id;
this.trialCount = trialCount;
this.createdTime = createdTime;
}

public RacingGameEntity(int trialCount) {
this(null, trialCount, LocalDateTime.now());
}

public int getTrialCount() {
return trialCount;
}

public Long getId() {
return id;
}

public LocalDateTime getCreatedTime() {
return createdTime;
}
}
Loading