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

[Spring 경로 조회 - 1단계] 후디(조동현) 미션 제출합니다. #203

Merged
merged 18 commits into from
May 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
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