SpringBoot와 DB연동
기능 설계
불러온 데이터 DB에 insert() 해보기
Architecture 설명
전체 인프라 아키텍처
API
HospitalDao insert()기능 구현
package com.springboot.hello.domain.dao;
import com.springboot.hello.domain.Hospital;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class HospitalDao {
private final JdbcTemplate jdbcTemplate;
public HospitalDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// 11만건의 데이터를 List<Hospital>에서 Hospital로 꺼내어 insert()
public void add(Hospital hospital) {
String sql = "insert into `testdb`.`nation_wide_hospitals` (`id`, `open_service_name`, `open_local_government_code`,\n" +
"`management_number`, `license_date`, `business_status`, `business_status_code`, `phone`, `full_address`, `road_name_address`, `hospital_name`,\n" +
"`business_type_name`, `healthcare_provider_count`, `patient_room_count`, `total_number_of_beds`,\n" +
"`total_area_size`) " +
"values (?, ?, ?, ?, ?, ?, ?,\n" +
"?, ?, ?, ?, ?, ?, ?, ?, ?)\n" +
" on duplicate key update `id`=?;";
this.jdbcTemplate.update(sql, hospital.getId(), hospital.getOpenServiceName(), hospital.getOpenLocalGovernmentCode(),
hospital.getManagementNumber(), hospital.getLicenseDate(), hospital.getBusinessStatus(), hospital.getBusinessStatusCode(), hospital.getPhone(), hospital.getFullAddress(), hospital.getRoadNameAddress(), hospital.getHospitalName(),
hospital.getBusinessTypeName(), hospital.getHealthcareProviderCnt(), hospital.getPatientRoomCnt(), hospital.getTotalNumberOfBeds(), hospital.getTotalAreaSize(), hospital.getId());
}
}
Java
복사
HospitalParserTest add()메서드 테스트 코드 추가
@Test
@DisplayName("Hospital이 insert가 잘 되는지")
void add() {
HospitalParser hp = new HospitalParser(); // 껍데기 (데이터 존재❌)
Hospital hospital = hp.parse(line1);
hospitalDao.add(hospital);
}
Java
복사
@Component 가 달린 클래스를 Bean으로 등록해주어 HospitalDao는 Factory가 없어도 DI를 적용할 수 있게 됨
national_wide_hospital 테이블 수정하기
DB 테이블 명세서
getCount(), deleteAll() 구현하기
package com.springboot.hello.domain.dao;
import com.springboot.hello.domain.Hospital;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
@Component
public class HospitalDao {
private final JdbcTemplate jdbcTemplate;
public HospitalDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// 11만건의 데이터를 List<Hospital>에서 Hospital로 꺼내어 insert()
public void add(Hospital hospital) {
String sql = "insert into `testdb`.`nation_wide_hospitals` (`id`, `open_service_name`, `open_local_government_code`,\n" +
"`management_number`, `license_date`, `business_status`, `business_status_code`, `phone`, `full_address`, `road_name_address`, `hospital_name`,\n" +
"`business_type_name`, `healthcare_provider_count`, `patient_room_count`, `total_number_of_beds`,\n" +
"`total_area_size`) " +
"values (?, ?, ?, ?, ?, ?, ?,\n" +
"?, ?, ?, ?, ?, ?, ?, ?, ?)\n" +
" on duplicate key update `id`=?;";
this.jdbcTemplate.update(sql, hospital.getId(), hospital.getOpenServiceName(), hospital.getOpenLocalGovernmentCode(),
hospital.getManagementNumber(), hospital.getLicenseDate(), hospital.getBusinessStatus(), hospital.getBusinessStatusCode(), hospital.getPhone(), hospital.getFullAddress(), hospital.getRoadNameAddress(), hospital.getHospitalName(),
hospital.getBusinessTypeName(), hospital.getHealthcareProviderCnt(), hospital.getPatientRoomCnt(), hospital.getTotalNumberOfBeds(), hospital.getTotalAreaSize(), hospital.getId());
}
public Hospital findById(String sId) {
String sql = "select * from `testdb`.`nation_wide_hospitals` where `id`=?";
RowMapper<Hospital> rowMapper = new RowMapper<Hospital>() {
@Override
public Hospital mapRow(ResultSet rs, int rowNum) throws SQLException {
Hospital hospital = new Hospital(rs.getInt("id"), rs.getString("open_service_name"), rs.getInt("open_local_government_code"),
rs.getString("management_number"), rs.getObject("license_date", LocalDateTime.class), rs.getInt("business_status"), rs.getInt("business_status_code"), rs.getString("phone"), rs.getString("full_address"), rs.getString("road_name_address"),
rs.getString("hospital_name"), rs.getString("business_type_name"), rs.getInt("healthcare_provider_count"), rs.getInt("patient_room_cnt"), rs.getInt("total_number_of_beds"), rs.getFloat("total_area_size"));
return hospital;
}
};
return this.jdbcTemplate.queryForObject(sql, rowMapper, sId);
}
public int deleteAll() {
String sql = "delete from `testdb`.`nation_wide_hospitals`;";
return this.jdbcTemplate.update(sql);
}
public int getCount() {
String sql = "select count(id) from `testdb`.`nation_wide_hospitals`;";
return this.jdbcTemplate.queryForObject(sql, Integer.class);
}
}
Java
복사
package com.springboot.hello.parser;
import com.springboot.hello.domain.Hospital;
import com.springboot.hello.domain.dao.HospitalDao;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
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\",\"\",";
String line2 = "\"2\",\"의원\",\"01_01_02_P\",\"3620000\",\"PHMA119993620020041100005\",\"19990707\",\"\",\"01\",\"영업/정상\",\"13\",\"영업중\",\"\",\"\",\"\",\"\",\"062-574-2802\",\"\",\"500867\",\"광주광역시 북구 일곡동 821번지 1호 2층\",\"광주광역시 북구 설죽로 518, 2층 (일곡동)\",\"61041\",\"일곡부부치과의원\",\"20170905183213\",\"I\",\"2018-08-31 11:59:59 PM\",\"치과의원\",\"190646.777107\",\"189589.427851\",\"치과의원\",\"2\",\"0\",\"0\",\"200\",\"401\",\"치과\",\"\",\"\",\"\",\"0\",\"0\",\"\",\"\",\"0\",\"\",";
@Autowired
ReadLineContext<Hospital> hospitalReadLineContext;
@Autowired
HospitalDao hospitalDao;
@Test
@Order(3)
@DisplayName("Hospital이 insert가 잘 되는지")
void add() {
HospitalParser hp = new HospitalParser();
Hospital hospital = hp.parse(line1);
Hospital hospital2 = hp.parse(line2);
hospitalDao.add(hospital);
hospitalDao.add(hospital2);
assertEquals(2, hospitalDao.getCount());
}
@Test
@Order(4)
@DisplayName("병의원 데이터수 세기")
void getCount() {
System.out.printf("전국 병의원 데이터 수 : %d", hospitalDao.getCount());
assertEquals(2, hospitalDao.getCount());
}
@Test
@Order(5)
@DisplayName("모든 데이터 삭제 테스트")
void deleteAll() {
hospitalDao.deleteAll();
assertEquals(0, hospitalDao.getCount());
}
@Test
@Order(1)
@DisplayName("10만건 이상 데이터 파싱 테스트")
void onHundredThousandRows() throws IOException {
String filename = "C:\\TECHIT\\fulldata_01_01_02_P_의원.csv";
List<Hospital> hospitalList = hospitalReadLineContext.readLineParser(filename);
System.out.printf("파싱된 데이터 개수 : ", hospitalList.size());
assertTrue(hospitalList.size() > 1000);
assertTrue(hospitalList.size() > 10000);
/*for (int i = 0; i < 10; i++) {
System.out.println(hospitalList.get(i).getHospitalName());
}*/
System.out.printf("파싱된 데이터 개수 : ", hospitalList.size());
}
@Test
@Order(2)
@DisplayName("csv 1줄 hospital로 잘 만드는지 테스트")
void convertToHospital() {
HospitalParser hp = new HospitalParser();
Hospital hospital = hp.parse(line1);
assertEquals(1, hospital.getId()); // 0
assertEquals("의원", hospital.getOpenServiceName()); // 1
assertEquals(3620000,hospital.getOpenLocalGovernmentCode()); // 3
assertEquals("PHMA119993620020041100004",hospital.getManagementNumber()); // 4
assertEquals(LocalDateTime.of(1999, 6, 12, 0, 0, 0), hospital.getLicenseDate()); // 5
assertEquals(1, hospital.getBusinessStatus()); // 7
assertEquals(13, hospital.getBusinessStatusCode()); // 9
assertEquals("062-515-2875", hospital.getPhone()); // 15
assertEquals("광주광역시 북구 풍향동 565번지 4호 3층", hospital.getFullAddress()); // 18
assertEquals("광주광역시 북구 동문대로 24, 3층 (풍향동)", hospital.getRoadNameAddress()); // 19
assertEquals("효치과의원", hospital.getHospitalName()); // 21
assertEquals("치과의원", hospital.getBusinessTypeName()); // 25
assertEquals(1, hospital.getHealthcareProviderCnt()); // 29
assertEquals(0, hospital.getPatientRoomCnt()); // 30
assertEquals(0, hospital.getTotalNumberOfBeds()); // 31
assertEquals(52.29f, hospital.getTotalAreaSize()); // 32
}
}
Java
복사
selectById() 구현하기
public Hospital selectById(String sId) {
String sql = "select * from `testdb`.`nation_wide_hospitals` where `id`=?";
RowMapper<Hospital> rowMapper = new RowMapper<Hospital>() {
@Override
public Hospital mapRow(ResultSet rs, int rowNum) throws SQLException {
Hospital hospital = new Hospital(rs.getInt("id"), rs.getString("open_service_name"), rs.getInt("open_local_government_code"),
rs.getString("management_number"), rs.getObject("license_date", LocalDateTime.class), rs.getInt("business_status"), rs.getInt("business_status_code"), rs.getString("phone"), rs.getString("full_address"), rs.getString("road_name_address"),
rs.getString("hospital_name"), rs.getString("business_type_name"), rs.getInt("healthcare_provider_count"), rs.getInt("patient_room_count"), rs.getInt("total_number_of_beds"), rs.getFloat("total_area_size"));
return hospital;
}
};
return this.jdbcTemplate.queryForObject(sql, rowMapper, sId);
}
Java
복사
@Test
@DisplayName("찾고자 하는 병의원 데이터가 잘나오는지")
void selectById() {
Hospital hospital = hospitalDao.selectById("1");
assertEquals(1, hospital.getId());
assertEquals("의원", hospital.getOpenServiceName());
assertEquals(3620000, hospital.getOpenLocalGovernmentCode());
assertEquals("PHMA119993620020041100004", hospital.getManagementNumber());
assertEquals(LocalDateTime.of(1999, 06, 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.getHealthcareProviderCnt());
assertEquals(0, hospital.getPatientRoomCnt());
assertEquals(0, hospital.getTotalNumberOfBeds());
assertEquals(52.29f, hospital.getTotalAreaSize());
}
Java
복사
selectById() Refactoring
RowMapper<Hospital> rowMapper = (rs, rowNum) -> {
Hospital hospital = new Hospital();
hospital.setId(rs.getInt("id"));
hospital.setOpenServiceName(rs.getString("open_service_name"));
hospital.setOpenLocalGovernmentCode(rs.getInt("open_local_government_code"));
hospital.setManagementNumber(rs.getString("management_number"));
hospital.setLicenseDate(rs.getTimestamp("license_date").toLocalDateTime());
hospital.setBusinessStatus(rs.getInt("business_status"));
hospital.setBusinessStatusCode(rs.getInt("business_status_code"));
hospital.setPhone(rs.getString("phone"));
hospital.setFullAddress(rs.getString("full_address"));
hospital.setRoadNameAddress(rs.getString("road_name_address"));
hospital.setHospitalName(rs.getString("hospital_name"));
hospital.setBusinessTypeName(rs.getString("business_type_name"));
hospital.setHealthcareProviderCnt(rs.getInt("healthcare_provider_count"));
hospital.setPatientRoomCnt(rs.getInt("patient_room_count"));
hospital.setTotalNumberOfBeds(rs.getInt("total_number_of_beds"));
hospital.setTotalAreaSize(rs.getFloat("total_area_size"));
return hospital;
};
public Hospital selectById(int sId) {
String sql = "select * from `testdb`.`nation_wide_hospitals` where `id`=?";
return this.jdbcTemplate.queryForObject(sql, rowMapper, sId);
}
Java
복사
@Test
@Order(4)
@DisplayName("찾고자 하는 병의원 데이터가 잘나오는지")
void selectById() {
HospitalParser hp = new HospitalParser();
Hospital hospital = hp.parse(line1);
Hospital selectedHospital = hospitalDao.selectById(hospital.getId());
assertEquals(selectedHospital.getId(), hospital.getId());
assertEquals(selectedHospital.getOpenServiceName(), hospital.getOpenServiceName());
assertEquals(selectedHospital.getOpenLocalGovernmentCode(),hospital.getOpenLocalGovernmentCode());
assertEquals(selectedHospital.getManagementNumber(),hospital.getManagementNumber());
assertEquals(selectedHospital.getBusinessStatus(), hospital.getBusinessStatus()); // idx:7
assertEquals(selectedHospital.getBusinessStatusCode(), hospital.getBusinessStatusCode());
assertTrue(selectedHospital.getLicenseDate().isEqual(hospital.getLicenseDate()));
assertEquals(selectedHospital.getPhone(), hospital.getPhone());
assertEquals(selectedHospital.getFullAddress(), hospital.getFullAddress());
assertEquals(selectedHospital.getRoadNameAddress(), hospital.getRoadNameAddress());
assertEquals(selectedHospital.getHospitalName(), hospital.getHospitalName());
assertEquals(selectedHospital.getBusinessTypeName(), hospital.getBusinessTypeName());
assertEquals(selectedHospital.getHealthcareProviderCnt(), hospital.getHealthcareProviderCnt());
assertEquals(selectedHospital.getPatientRoomCnt(), hospital.getPatientRoomCnt());
assertEquals(selectedHospital.getTotalNumberOfBeds(), hospital.getTotalNumberOfBeds());
assertEquals(selectedHospital.getTotalAreaSize(), hospital.getTotalAreaSize());
}
Java
복사