Skip to content

Commit

Permalink
Merge pull request #203 from devHudi/step1
Browse files Browse the repository at this point in the history
[Spring 경로 조회 - 1단계] 후디(조동현) 미션 제출합니다.
  • Loading branch information
ksy90101 authored May 20, 2022
2 parents 9b68357 + 67a6203 commit 93b27df
Show file tree
Hide file tree
Showing 53 changed files with 3,203 additions and 188 deletions.
50 changes: 11 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,11 @@
<p align="center">
<img width="200px;" src="https://raw.githubusercontent.com/woowacourse/atdd-subway-admin-frontend/master/images/main_logo.png"/>
</p>
<p align="center">
<a href="https://techcourse.woowahan.com/c/Dr6fhku7" alt="woowacuorse subway">
<img alt="Website" src="https://img.shields.io/website?url=https%3A%2F%2Fedu.nextstep.camp%2Fc%2FR89PYi5H">
</a>
<img alt="GitHub" src="https://img.shields.io/github/license/woowacourse/atdd-subway-path">
</p>

<br>

# 지하철 노선도 미션
스프링 과정 실습을 위한 지하철 노선도 애플리케이션

<br>

## 🚀 Getting Started
### Usage
#### application 구동
```
./gradlew bootRun
```
<br>

## ✏️ Code Review Process
[텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview)

<br>

## 🐞 Bug Report

버그를 발견한다면, [Issues](https://github.com/woowacourse/atdd-subway-path/issues) 에 등록해주세요 :)

<br>

## 📝 License

This project is [MIT](https://github.com/woowacourse/atdd-subway-path/blob/master/LICENSE) licensed.
## 지하철 노선도 최단경로 미션 기능구현 목록

- [x] 출발역과 도착역을 전달받아 최단경로 조회
- [x] 경로 요금 계산
> 기본운임(10㎞ 이내): 기본운임 1,250원
>
> 이용 거리 초과 시 추가운임 부과
>
> 10km~50km: 5km 까지 마다 100원 추가
>
> 50km 초과: 8km 까지 마다 100원 추가
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies {
// spring
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-validation'

// log
implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1'
Expand Down
1 change: 0 additions & 1 deletion src/main/java/wooteco/subway/SubwayApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ public class SubwayApplication {
public static void main(String[] args) {
SpringApplication.run(SubwayApplication.class, args);
}

}
3 changes: 2 additions & 1 deletion src/main/java/wooteco/subway/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*").allowedOriginPatterns("*");
}
}
}
91 changes: 91 additions & 0 deletions src/main/java/wooteco/subway/dao/LineDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package wooteco.subway.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;
import wooteco.subway.domain.Line;
import wooteco.subway.domain.Section;
import wooteco.subway.domain.Station;

@Repository
public class LineDao {

private static final String NON_EXISTENT_ID_EXCEPTION = "존재하지 않는 id입니다.";

private final JdbcTemplate jdbcTemplate;

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

public Line save(Line line) {
final SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate)
.withTableName("line").usingGeneratedKeyColumns("id");

Map<String, Object> parameters = new HashMap<>();
parameters.put("name", line.getName());
parameters.put("color", line.getColor());

final Number number = simpleJdbcInsert.executeAndReturnKey(parameters);
return Line.createWithoutSection(number.longValue(), line.getName(), line.getColor());
}

public boolean existsByName(String name) {
final String sql = "SELECT COUNT(*) FROM line WHERE name = ?";
final Integer numOfLine = jdbcTemplate.queryForObject(sql, Integer.class, name);
return !numOfLine.equals(0);
}

public List<Line> findAll() {
final String sql = "SELECT * FROM line";
return jdbcTemplate.query(sql, this::lineMapper);
}

public Line findById(Long id) {
final String sql = "SELECT * FROM line WHERE id = ?";
return jdbcTemplate.queryForObject(sql, this::lineMapper, id);
}

private Line lineMapper(ResultSet rs, int rowNum) throws SQLException {
return Line.createWithId(
rs.getLong("id"),
rs.getString("name"),
rs.getString("color"),
findSectionsByLineId(rs.getLong("id"))
);
}

private List<Section> findSectionsByLineId(Long lineId) {
final String sql =
"select s.id sid, s.distance sdistance, us.id usid, us.name usname, ds.id dsid, ds.name dsname " +
"from sections s " +
"join station us on s.up_station_id = us.id " +
"join station ds on s.down_station_id = ds.id " +
"where line_id = ?";
return jdbcTemplate.query(sql, ((rs, rowNum) -> {
return Section.createWithId(rs.getLong("sid"), new Station(rs.getLong("usid"), rs.getString("usname")),
new Station(rs.getLong("dsid"), rs.getString("dsname")), rs.getInt("sdistance"));
}), lineId);
}

public void updateLineById(Long id, String name, String color) {
final String sql = "UPDATE line SET name=?, color=? WHERE id=?";
validateResult(jdbcTemplate.update(sql, name, color, id));
}

public void deleteById(Long id) {
final String sql = "DELETE FROM line WHERE id = ?";
validateResult(jdbcTemplate.update(sql, id));
}

private void validateResult(int result) {
if (result == 0) {
throw new IllegalArgumentException(NON_EXISTENT_ID_EXCEPTION);
}
}
}
61 changes: 61 additions & 0 deletions src/main/java/wooteco/subway/dao/SectionDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package wooteco.subway.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.Repository;
import wooteco.subway.domain.Section;
import wooteco.subway.domain.Station;

@Repository
public class SectionDao {

private final JdbcTemplate jdbcTemplate;

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

public void save(List<Section> sections, Long lineId) {
batchInsert(sections, lineId);
}

public List<Section> findAll() {
final String sql =
"select s.id sid, s.distance sdistance, us.id usid, us.name usname, ds.id dsid, ds.name dsname " +
"from sections s " +
"join station us on s.up_station_id = us.id " +
"join station ds on s.down_station_id = ds.id";
return jdbcTemplate.query(sql, ((rs, rowNum) -> {
return Section.createWithId(rs.getLong("sid"), new Station(rs.getLong("usid"), rs.getString("usname")),
new Station(rs.getLong("dsid"), rs.getString("dsname")), rs.getInt("sdistance"));
}));
}

private int[] batchInsert(List<Section> sections, Long lineId) {
return this.jdbcTemplate.batchUpdate(
"insert into sections (line_id, up_station_id, down_station_id, distance) values (?, ?, ?, ?)",
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setLong(1, lineId);
ps.setLong(2, sections.get(i).getUpStation().getId());
ps.setLong(3, sections.get(i).getDownStation().getId());
ps.setInt(4, sections.get(i).getDistance().getValue());
}

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

public void deleteByLineId(Long lineId) {
final String sql = "delete from sections where line_id = ?";
jdbcTemplate.update(sql, lineId);
}
}
73 changes: 54 additions & 19 deletions src/main/java/wooteco/subway/dao/StationDao.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,65 @@
package wooteco.subway.dao;

import org.springframework.util.ReflectionUtils;
import wooteco.subway.domain.Station;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;
import wooteco.subway.domain.Station;

@Repository
public class StationDao {
private static Long seq = 0L;
private static List<Station> stations = new ArrayList<>();

public static Station save(Station station) {
Station persistStation = createNewObject(station);
stations.add(persistStation);
return persistStation;
private static final String NON_EXISTENT_ID_EXCEPTION = "존재하지 않는 id입니다.";

private final JdbcTemplate jdbcTemplate;
private final RowMapper<Station> stationRowMapper = (resultSet, rowNum) -> new Station(
resultSet.getLong("id"),
resultSet.getString("name")
);

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

public Station save(Station station) {
final SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate)
.withTableName("station").usingGeneratedKeyColumns("id");

Map<String, Object> parameters = new HashMap<>();
parameters.put("name", station.getName());

final Number number = simpleJdbcInsert.executeAndReturnKey(parameters);
return new Station(number.longValue(), station.getName());
}

public List<Station> findAll() {
final String sql = "SELECT * FROM station";

return jdbcTemplate.query(sql, stationRowMapper);
}

public boolean existsByName(String name) {
final String sql = "select count(*) from station where name = ?";
final Integer numOfStation = jdbcTemplate.queryForObject(sql, Integer.class, name);
return !numOfStation.equals(0);
}

public void deleteById(Long id) {
final String sql = "DELETE FROM station where id = ?";
validateResult(jdbcTemplate.update(sql, id));
}

public static List<Station> findAll() {
return stations;
private void validateResult(int result) {
if (result == 0) {
throw new IllegalArgumentException(NON_EXISTENT_ID_EXCEPTION);
}
}

private static Station createNewObject(Station station) {
Field field = ReflectionUtils.findField(Station.class, "id");
field.setAccessible(true);
ReflectionUtils.setField(field, station, ++seq);
return station;
public Station findById(Long id) {
final String sql = "SELECT * FROM station WHERE id = ?";
return jdbcTemplate.queryForObject(sql, stationRowMapper, id);
}
}
}
63 changes: 63 additions & 0 deletions src/main/java/wooteco/subway/domain/Distance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package wooteco.subway.domain;

import java.util.Objects;

public class Distance {

private final int value;

public Distance(int value) {
validatePositive(value);
this.value = value;
}

public Distance(double value) {
this((int) value);
}

private void validatePositive(int value) {
if (value <= 0) {
throw new IllegalArgumentException("거리는 0이하가 될 수 없습니다.");
}
}

public Distance add(Distance other) {
return new Distance(value + other.value);
}

public Distance subtract(Distance other) {
return new Distance(value - other.value);
}

public boolean isLessThanOrEqualTo(Distance other) {
return value <= other.value;
}

public int getValue() {
return value;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Distance distance = (Distance) o;
return value == distance.value;
}

@Override
public int hashCode() {
return Objects.hash(value);
}

@Override
public String toString() {
return "Distance{" +
"value=" + value +
'}';
}
}
Loading

0 comments on commit 93b27df

Please sign in to comment.