//////
Search
🍒

[1031] Hospital 파싱 실습

생성일
2022/11/10 07:58
태그
TodayILearn
Spring
java
생성일 1
목차
// testcode 10만명 파싱하기 에러를 아직 고치지 못한 코드입니다.
→ 코드에 문제 없었고, 데이터 UTF-8 인코딩 과정에서 발생한 에러였습니다

전국 병의원 정보 검색 API 만들기

FileLineParser 실습 진행 : fulldata_01_01_02_P_의원.csv

1.
전국 병원 정보가 들어갈 table 설게
2.
create table
3.
table에 넣기위한 domain class 만들기

테이블 설계

코드
컬럼 타입을 세분화 하는 이유 db에 저장공간을 줄이고, 검색 속도를 최적화 하기 위함
tinyint - 작은 int 범위가 작지만 int에 비해 공간을 덜 차지 한다.
datetime - where 조건에 날짜 from to
float – 소수점 int에 넣으면 소수점이 잘리기 때문 int에 비해 공간을 더 차지 한다.
varchar - 한글은 한 글자당 2byte사용된다.
no
컬럼 위치
컬럼명
Java
타입
설명
1
0
id(pk)
id
Int
번호
2
1
open_service_name
openServiceName
VARCHAR(10)
개방서비스명
3
3
open_local_government_code
openLocalGovernmentCode
int
개방자치단체코드
4
4
management_number(unique)
managementNumber
varchar(40)
관리번호
5
5
license_date
license_date
datetime
인허가일자
6
7
business_status
businessStatus
tinyint(2)
1: 영업/정상 2: 휴업 3: 폐업 4: 취소/말소영업상태구분
7
9
business_status_code
businessStatusCode
tinyint(2)
영업상태코드 2: 휴업 3: 폐업 13: 영업중
8
15
phone
phone
varchar(20)
소재지전화
9
18
full_address
fullAddress
VARCHAR(200)
소재지전체주소
10
19
road_name_address
roadNameAddress
VARCHAR(200)
도로명전체주소
11
21
hospital_name
hospitalName
VARCHAR(20)
사업장명(병원이름)
12
25
business_type_name
businessTypeName
VARCHAR(10)
업태구분명
13
29
healthcare_provider_count
healthcareProviderCount
tinyint(2)
의료인수
14
30
patient_room_count
patientRoomCount
tinyint(2)
입원실수
15
31
total_number_of_beds
totalNumberOfBeds
tinyint(2)
병상수
16
32
total_area_size
totalAreaSize
float
총면적

Create Table

코드 구현

1. 도메인 hospital 생성

Lombok 이용 : 칼럼이 추가되거나 제거되어도 Constructor, Gettter, Setter을 수정하지 않고 사용할 수 있어서 편하다.
@AllArgsConstructor @Getter @Setter @NoArgsConstructor // 빈 public class Hospital { private int id; private String openServiceName; // java는 camel case로 변수작성 private int openLocalGovernmentCode; private String managementNumber; private LocalDateTime licenseDate; private int businessStatus; private int businessStatusCode; private String phone; private String fullAddress; private String roadNameAddress; private String hospitalName; private String businessTypeName; private int healthcareProviderCount; private int patientRoomCount; private int totalNumberOfBeds; private float totalAreaSize; }
Java
복사
hospital.java

2. HospitalParser.java 구현

public interface Parser<T> { T parse(String str); }
Java
복사
Parser.java
String에서 따옴표 제거
public class HospitalParser implements Parser<Hospital> { @Override public Hospital parse(String str) { // \"...\"를 기준으로 split String[] row = str.split("\",\""); // 객체 생성 Hospital hospital = new Hospital(); // row 배열을 출력 System.out.println(Arrays.toString(row)); return hospital; } }
Java
복사
HospitalParser.java

3. 테스트 코드 작성

Alt + enter
testCode 1
class HospitalParserTest { String line1 = "\"1\",\"의원\",\"01_01_02_P\",\"3620000\",\"PHMA119993620020041100004\",\"19990612\",\"\",\"01\",\"영업/정상\",\"13\",\"영업중\",\"\",\"\",\"\",\"\",\"062-515-2875\",\"\",\"500881\",\"광주광역시 북구 풍향동 565번지 4호 3층\",\"광주광역시 북구 동문대로 24, 3층 (풍향동)\",\"61205\",\"효치과의원\",\"20211115113642\",\"U\",\"2021-11-17 02:40:00.0\",\"치과의원\",\"192630.735112\",\"185314.617632\",\"치과의원\",\"1\",\"0\",\"0\",\"52.29\",\"401\",\"치과\",\"\",\"\",\"\",\"0\",\"0\",\"\",\"\",\"0\",\"\","; @Test @DisplayName("csv 1 줄을 Hospital로 잘 만드는지 test") void convertToHospital() { HospitalParser hp = new HospitalParser(); Hospital hospital = hp.parse(line1); } }
Java
복사
결과 확인

4. HospitalParser에서 Setter로 값을 설정하고, HospitalParserTest에서 Getter로 값을 가져와 비교

4_1. Map Reduce : 병렬처리 후 합치기

맨 앞과 맨 뒤의 “ “를 제거하기 위해 replace()를 활용했다.
replace
replace함수는 자신이 바꾸고싶은 문자로 문자열을 치환시켜주는 기능을 한다.
ex) a.replace(바꾸고 싶은 부분, 바꿀 문자열)
DateTime
substring
년,월,일을 표시하기 위해 문자열을 substring()을 활용했다.
// LocalDatetTime 클래스 사용하여 DateTime 구하기 int year = Integer.parseInt(row[5].substring(0, 4)); int month = Integer.parseInt(row[5].substring(4, 6)); int day = Integer.parseInt(row[5].substring(6, 8)); // System.out.printf("%d %d %d \n", year, month, day); hospital.setLicenseDate(LocalDateTime.of(year, month, day, 0, 0, 0));
Java
복사
전체 코드

4_2. Test 코드에서 실행확인

class HospitalParserTest { String line1 = "\"1\",\"의원\",\"01_01_02_P\",\"3620000\",\"PHMA119993620020041100004\",\"19990612\",\"\",\"01\",\"영업/정상\",\"13\",\"영업중\",\"\",\"\",\"\",\"\",\"062-515-2875\",\"\",\"500881\",\"광주광역시 북구 풍향동 565번지 4호 3층\",\"광주광역시 북구 동문대로 24, 3층 (풍향동)\",\"61205\",\"효치과의원\",\"20211115113642\",\"U\",\"2021-11-17 02:40:00.0\",\"치과의원\",\"192630.735112\",\"185314.617632\",\"치과의원\",\"1\",\"0\",\"0\",\"52.29\",\"401\",\"치과\",\"\",\"\",\"\",\"0\",\"0\",\"\",\"\",\"0\",\"\","; @Test @DisplayName("csv 1 줄을 Hospital로 잘 만드는지 test") void convertToHospital() { HospitalParser hp = new HospitalParser(); Hospital hospital = hp.parse(line1); assertEquals(1, hospital.getId()); assertEquals("의원", hospital.getOpenServiceName()); assertEquals(3620000,hospital.getOpenLocalGovernmentCode()); assertEquals("PHMA119993620020041100004",hospital.getManagementNumber()); assertEquals(LocalDateTime.of(1999,6,12,0,0,0), hospital.getLicenseDate()); assertEquals(1, hospital.getBusinessStatus()); assertEquals(13, hospital.getBusinessStatusCode()); assertEquals("062-515-2875", hospital.getPhone()); assertEquals("광주광역시 북구 풍향동 565번지 4호 3층", hospital.getFullAddress()); assertEquals("광주광역시 북구 동문대로 24, 3층 (풍향동)", hospital.getRoadNameAddress()); assertEquals("효치과의원", hospital.getHospitalName()); assertEquals("치과의원", hospital.getBusinessTypeName()); assertEquals(1, hospital.getHealthcareProviderCount()); assertEquals(0, hospital.getPatientRoomCount()); assertEquals(0, hospital.getTotalNumberOfBeds()); assertEquals(52.29f, hospital.getTotalAreaSize()); } }
Java
복사
결과 확인

수동으로 IoC와 Di하기 : Factory

1.
Parser 디렉토리에 ParserFactory 생성, ReadLineContext 생성
ReadLineContext.java
ParserFactory
2.
SpringBoot 사용
a.
추가 : @SpringBootTest @Autowired
b.
Test 파일에 데이터를 가져와서 파싱하는 것까지 Test
@SpringBootTest class HospitalParserTest { String line1 = "\"1\",\"의원\",\"01_01_02_P\",\"3620000\",\"PHMA119993620020041100004\",\"19990612\",\"\",\"01\",\"영업/정상\",\"13\",\"영업중\",\"\",\"\",\"\",\"\",\"062-515-2875\",\"\",\"500881\",\"광주광역시 북구 풍향동 565번지 4호 3층\",\"광주광역시 북구 동문대로 24, 3층 (풍향동)\",\"61205\",\"효치과의원\",\"20211115113642\",\"U\",\"2021-11-17 02:40:00.0\",\"치과의원\",\"192630.735112\",\"185314.617632\",\"치과의원\",\"1\",\"0\",\"0\",\"52.29\",\"401\",\"치과\",\"\",\"\",\"\",\"0\",\"0\",\"\",\"\",\"0\",\"\","; @Autowired ReadLineContext<Hospital> hospitalReadLineContext; @Test @DisplayName("10만건 이상 데이터가 파싱되는지") void name() throws IOException { String filname = "C:\\Users\\wjdtk\\Downloads\\fulldata_의원.csv"; List<Hospital> hospitalList = hospitalReadLineContext.readByLine(filname); assertTrue(hospitalList.size()>10000); assertTrue(hospitalList.size()>100000); } @Test @DisplayName("csv 1 줄을 Hospital로 잘 만드는지 test") void convertToHospital() { HospitalParser hp = new HospitalParser(); Hospital hospital = hp.parse(line1); assertEquals(1, hospital.getId()); assertEquals("의원", hospital.getOpenServiceName()); assertEquals(3620000,hospital.getOpenLocalGovernmentCode()); assertEquals("PHMA119993620020041100004",hospital.getManagementNumber()); assertEquals(LocalDateTime.of(1999,6,12,0,0,0), hospital.getLicenseDate()); assertEquals(1, hospital.getBusinessStatus()); assertEquals(13, hospital.getBusinessStatusCode()); assertEquals("062-515-2875", hospital.getPhone()); assertEquals("광주광역시 북구 풍향동 565번지 4호 3층", hospital.getFullAddress()); assertEquals("광주광역시 북구 동문대로 24, 3층 (풍향동)", hospital.getRoadNameAddress()); assertEquals("효치과의원", hospital.getHospitalName()); assertEquals("치과의원", hospital.getBusinessTypeName()); assertEquals(1, hospital.getHealthcareProviderCount()); assertEquals(0, hospital.getPatientRoomCount()); assertEquals(0, hospital.getTotalNumberOfBeds()); assertEquals(52.29f, hospital.getTotalAreaSize()); } }
Java
복사