Skip to content

Commit

Permalink
release/0401-01
Browse files Browse the repository at this point in the history
release/0401-01
  • Loading branch information
Bisi3asi authored Mar 31, 2024
1 parent 1bb12b2 commit 57bfa9a
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 15 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ repositories {
}

dependencies {
// Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'

// REDIS
Expand Down Expand Up @@ -93,6 +94,8 @@ dependencies {
/// httpclient
implementation 'org.apache.httpcomponents.client5:httpclient5:5.1.3' // Apache HttpClient 5.x 의존성 추가

// hibernate spatial
implementation 'org.hibernate:hibernate-spatial:6.4.1.Final'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
import java.util.Optional;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class ChargerApiItemForm {
private String statNm;
private String statId;
Expand Down Expand Up @@ -44,8 +46,10 @@ public class ChargerApiItemForm {
public ChargerApiItemForm(Map<String, Object> item, DateTimeFormatter formatter) {
this.statNm = (String)item.get("statNm");
this.statId = (String)item.get("statId");
this.chgerId = String.valueOf(Integer.parseInt((String)item.get("chgerId")));
this.chgerType = String.valueOf(Integer.parseInt((String)item.get("chgerType")));
String _chgerId = (String) item.get("chgerId");
this.chgerId = !_chgerId.isEmpty() ?
String.valueOf(Integer.parseInt(_chgerId)) : _chgerId;
this.chgerType = (String)item.get("chgerType");
this.addr = (String)item.get("addr");
this.location = (String)item.get("location");
this.lat = Double.valueOf((String)item.get("lat"));
Expand Down Expand Up @@ -73,7 +77,7 @@ public ChargerApiItemForm(Map<String, Object> item, DateTimeFormatter formatter)
this.output = (String)item.get("output");
this.method = (String)item.get("method");
this.zcode = (String)item.get("zcode");
String _zscode = (String)item.get("zcode");
String _zscode = (String)item.get("zscode");
this.zscode = _zscode.length() == 5 ? _zscode.substring(0, 4)+"0" : _zscode;
this.kind = (String)item.get("kind");
this.kindDetail = (String)item.get("kindDetail");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public HashMap webClientApiGetChargerStatus(
} catch (JsonProcessingException e) {
log.error("[ERROR] : OpenAPI 데이터 JSON 파싱 오류 {}", e.getMessage());
} catch(Exception e) {
log.error("[ERROR] : OpenAPI 데이터 불러오기 중 에러 발생(시간초과) {}", e.getMessage());
log.error("[ERROR] : OpenAPI 데이터 불러오기 중 에러 발생) {}", e.getMessage());
}
return hashMap;
}
Expand Down Expand Up @@ -131,8 +131,10 @@ public List<ChargerApiItemForm> webClientApiGetChargerInfo(
apiDataMap = objectMapper.readValue(response, HashMap.class);
} catch (JsonProcessingException e) {
log.error("[ERROR] : OpenAPI 데이터 JSON 파싱 오류 {}", e.getMessage());
return null;
} catch(Exception e) {
log.error("[ERROR] : OpenAPI 데이터 불러오기 중 에러 발생(시간초과) {}", e.getMessage());
log.error("[ERROR] : OpenAPI 데이터 불러오기 중 에러 발생 {}", e.getMessage());
return null;
}

List<Map<String, Object>> items = (List<Map<String, Object>>)((Map<String, Object>)apiDataMap.get("items")).get("item");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public List<ChargerApiItemForm> process(List<ChargerApiItemForm> item) {
.build()
)
.toList();

if (!newCompanyList.isEmpty()) {
log.info("[Batch] : 신규 기관 {}개 감지 및 저장 완료", newCompanyList.size());
companyRepository.saveAll(newCompanyList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public List<ChargerApiItemForm> read() {
List<ChargerApiItemForm> list = chargerService.webClientApiGetChargerInfo(
baseUrl, apiServiceKey, numOfRows,currentPageNo, dataType);

// 오류로 인해 API 데이터가 받아지지 않는 경우
if (list == null) {
return List.of(new ChargerApiItemForm());
}

log.info("[Batch] : 현재 불러온 OpenAPI 데이터 페이지 : {} 페이지", currentPageNo);

if (list.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Map;
import java.util.stream.Collectors;

import org.locationtech.jts.geom.GeometryFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ItemWriter;
Expand Down Expand Up @@ -32,6 +33,7 @@ public class ChargerApiBatchWriter implements ItemWriter<List<ChargerApiItemForm
private final OperatingCompanyRepository companyRepository;
private final ChargingStationRepository stationRepository;
private final ChargerRepository chargerRepository;
private final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();

@Override
public void write(Chunk<? extends List<ChargerApiItemForm>> chunk) {
Expand All @@ -47,6 +49,8 @@ public void write(Chunk<? extends List<ChargerApiItemForm>> chunk) {

try {
for (List<ChargerApiItemForm> items : chunk) {
if (items.isEmpty()) continue;

for (ChargerApiItemForm item : items) {
RegionDetail region = regionMap.get(item.getZscode());
OperatingCompany company = companyMap.get(item.getBusiId());
Expand All @@ -56,10 +60,14 @@ public void write(Chunk<? extends List<ChargerApiItemForm>> chunk) {
ChargingStation station = stationRepository.findById(item.getStatId()).orElse(null);
if (station != null) {
station.update(item, company, region);
station.setPoint(GEOMETRY_FACTORY, station);

updatingStationList.add(station);
updateStationCnt++;
} else {
station = new ChargingStation(item, company, region);
station.setPoint(GEOMETRY_FACTORY, station);

stationRepository.saveAndFlush(station);
insertStationCnt++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import java.util.ArrayList;
import java.util.List;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;

import com.ll.everycharge.domain.charger.charger.entity.Charger;
import com.ll.everycharge.domain.charger.charger.form.ChargerApiItemForm;
import com.ll.everycharge.domain.operatingCompany.operatingCompany.entity.OperatingCompany;
Expand Down Expand Up @@ -62,6 +66,8 @@ public class ChargingStation {
private double lat;
//경도
private double lng;
// 위도, 경도 point
private Point point;
//주차료여부
private String parkingFree;
//충전소 안내
Expand Down Expand Up @@ -115,4 +121,12 @@ public void update(ChargerApiItemForm item, OperatingCompany company, RegionDeta
this.operatingCompany = company;
this.regionDetail = regionDetail;
}

// MySQL Spatial Index를 위한 Point 칼럼 set
public void setPoint(GeometryFactory factory, ChargingStation chargingStation){
Point newPoint = factory.createPoint(
new Coordinate(chargingStation.getLng(), chargingStation.getLat()));
newPoint.setSRID(4326);
this.point = newPoint;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public Page<ChargingStationSearchBaseDistanceResponseDto> searchBaseDistance(

String nativeQuery =
"SELECT CS.stat_id AS statId, "
+ "ST_DISTANCE_SPHERE (POINT(CS.lng, CS.lat), POINT (:lng, :lat)) AS distance, "
+ "ST_DISTANCE_SPHERE (CS.point, ST_POINTFROMTEXT(CONCAT('POINT(', :lat, ' ', :lng, ')'), 4326)) AS distance, "
+ "CS.stat_nm AS statNm, "
+ "CS.addr AS addr, "
+ "CS.lat AS lat, "
Expand All @@ -57,11 +57,11 @@ public Page<ChargingStationSearchBaseDistanceResponseDto> searchBaseDistance(
+ "JOIN region_detail AS RD ON CS.zscode = RD.zscode "
+ "JOIN region AS R ON R.zcode = RD.zcode "
+ "JOIN operating_company AS OC ON OC.busi_id = CS.busi_id "
+ "WHERE (:parkingFree is null or CS.parking_free = :parkingFree) "
+ "AND (:limitYn is null or CS.limit_yn = :limitYn) "
+ "AND (:zscode is null or RD.zscode = :zscode) " + "AND (:zcode is null or R.zcode = :zcode) "
+ "AND (:isPrimary is null or OC.is_primary = :isPrimary) "
+ "AND (ST_DISTANCE_SPHERE (POINT(CS.lng, CS.lat), POINT (:lng, :lat)) <= :range) ";
+ "WHERE (:parkingFree is null or CS.parking_free = :parkingFree) "
+ "AND (:limitYn is null or CS.limit_yn = :limitYn) "
+ "AND (:zscode is null or RD.zscode = :zscode) " + "AND (:zcode is null or R.zcode = :zcode) "
+ "AND (:isPrimary is null or OC.is_primary = :isPrimary) "
+ "AND (ST_CONTAINS ((ST_BUFFER (ST_POINTFROMTEXT(CONCAT('POINT(', :lat, ' ', :lng, ')'), 4326), :range)), CS.point)) ";

// null에 따른 쿼리 추가
if (kw != null) {
Expand Down Expand Up @@ -90,6 +90,7 @@ public Page<ChargingStationSearchBaseDistanceResponseDto> searchBaseDistance(
.setParameter("lng", lng)
.setParameter("range", range);


// null 에 따른 파라미터 추가
if (kw != null) {
query.setParameter("kw", "%" + kw + "%");
Expand All @@ -108,9 +109,7 @@ public Page<ChargingStationSearchBaseDistanceResponseDto> searchBaseDistance(
int start = (int)pageable.getOffset();
int end = Math.min((start + pageable.getPageSize()), resultList.size());
Page<ChargingStationSearchBaseDistanceResponseDto> page = new PageImpl<>(
resultList.subList(start, end),
pageable,
resultList.size()
resultList.subList(start, end), pageable, resultList.size()
);

return page;
Expand Down
40 changes: 39 additions & 1 deletion src/main/resources/sql/data_changed.sql
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,42 @@ SET bnm = '이브이시스', is_primary = 'Y' WHERE busi_id = 'JA'; # 중앙제

# 03.24. 삭제 여부 및 삭제 사유 필드 충전소 -> 충전기 테이블로 칼럼 이동 (칼럼 인서트는 hibernate에 의해 실행)
alter table charging_station drop column del_yn;
alter table charging_station drop column del_detail;
alter table charging_station drop column del_detail;

# 03.29. 공간 인덱스 도입
# hibernate update로 스키마 구성 시 공간 인덱스가 걸리지 않음 (spatial Index)
# 따라서 실행 전 charging_station 포함 연관관계 매핑되어 있는 모든 테이블을 삭제
# charging_station은 아래의 스키마를 통해 테이블 재구성, 인덱스 생성
# 그 외의 테이블은 기존과 동일하게 hibernate ddl update로 생성

# charging_station과 연관 테이블 드랍
drop table review;
drop table report;
drop table charger;
drop table technical_manager;
drop table charging_station;

# charging_station 스키마 재생성, 공간 인덱스 생성
CREATE TABLE charging_station (
stat_id VARCHAR(255) NOT NULL PRIMARY KEY,
zscode VARCHAR(255),
busi_id VARCHAR(255),
stat_nm VARCHAR(255),
addr VARCHAR(255),
location VARCHAR(255),
use_time VARCHAR(255),
lat DOUBLE NOT NULL,
lng DOUBLE NOT NULL,
parking_free VARCHAR(255),
note VARCHAR(255),
limit_yn VARCHAR(255),
limit_detail VARCHAR(255),
traffic_yn VARCHAR(255),
kind VARCHAR(255),
kind_detail VARCHAR(255),
point POINT NOT NULL SRID 4326,
CONSTRAINT fk_zscode FOREIGN KEY (zscode) REFERENCES region_detail (zscode),
CONSTRAINT fk_busi_id FOREIGN KEY (busi_id) REFERENCES operating_company (busi_id)
);

create spatial index idx_point on charging_station (point);

0 comments on commit 57bfa9a

Please sign in to comment.