728x90
Spring
DB Architecture
DB
Insert
public void add(Hospital hospital) {
String sql = "INSERT INTO `nation_wide_hospital` \\n" +
"(`id`, `open_service_name`, `open_local_government_code`, " +
"`management_number`, `license_date`, `business_status`, " +
"`business_status_code`, `phone`, `full_address`, " +
"`road_name_address`, `hospital_name`, `business_type_name`, " +
"`healthcare_provider_count`, `patient_room_count`, `total_number_of_beds`, " +
"`total_area_size`) \\n" +
"VALUES \\n" +
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
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.getHealthcareProviderCount(), hospital.getPatientRoomCount(), hospital.getTotalNumberOfBeds(),
hospital.getTotalAreaSize()
);
}
getCount()
public int getCount() {
String sql = "select count(*) from nation_wide_hospital";
return this.jdbcTemplate.queryForObject(sql, Integer.class);
}
- this.jdbcTemplate.queryForObject(sql, 어떤 자료형으로 내보낼지 정한다.)
- queryForObject(sql, String.class)를 사용했을 때 String으로 return되는 것을 확인.
public String getCount() { String sql = "select count(*) from nation_wide_hospital"; return this.jdbcTemplate.queryForObject(sql, String.class); } @Test void getCont() throws IOException, SQLException, ClassNotFoundException { String count = hospitalDao.getCount(); System.out.println(count); assertEquals("1", count); }
deleteAll()
public void deleteAll() {
this.jdbcTemplate.update("delete from nation_wide_hospitals");
}
findById()
RowMapper<Hospital> rowMapper = (rs, rowNum) -> {
Hospital hospital = new Hospital(
rs.getInt("id"),
rs.getString("open_service_name"),
rs.getInt("open_local_government_code"),
rs.getString("management_number"),
rs.getTimestamp("license_date").toLocalDateTime(),
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;
};
public Hospital findById(int id) throws ClassNotFoundException, SQLException {
String sql = "select * from nation_wide_hospital where id = ?";
return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}
중복 되는 RowMapper 부분을 따로 분리하였습니다.
RowMapper<Hospital> rowMapper = (rs, rowNum) -> {
}
- 람다식 사용시 매개변수의 자료형을 명시하지 않아도 해당 RowMapper 클래스에서 요구하는 자료형으로 자동 인식되는 것을 확인하였습니다.
RowMapper<Hospital> rowMapper = (abcd, efg) -> {
}
// 이상 없이 변수명으로 잘 활용이 된다.
- RowMapper의 Interface, mapRow가 매개변수의 자료형으로 ResultSet, int를 받고 있음을 확인하였습니다.
public interface RowMapper<T> {
@Nullable
T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
RowMapper
템플릿으로부터 ResultSet을 전달받고, 필요한 정보를 추출해서 리턴하는 방식으로 동작
ResultSet의 로우 하나만을 매핑하기 위해 사용.
Test
@SpringBootTest
class HospitalParserTest {
HospitalParser hp = new HospitalParser();
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;
@Autowired
HospitalDao hospitalDao;
@Test
void findById() throws IOException, SQLException, ClassNotFoundException {
Hospital hospital = hp.parse(line1);
Hospital hospital1 = hospitalDao.findById(1);
System.out.println(hospital1.getHospitalName());
assertEquals(hospital.getHospitalName(), hospital1.getHospitalName());
assertEquals(hospital1.getLicenseDate(), hospital.getLicenseDate());
}
@Test
void getCont() throws IOException, SQLException, ClassNotFoundException {
int count = hospitalDao.getCount();
System.out.println(count);
assertEquals(1, count);
}
@Test
void add(){
Hospital hospital = hp.parse(line1);
hospitalDao.add(hospital);
}
@Test
void name() throws IOException {
String filename = "P:\\\\TechIt\\\\교재\\\\fulldata_01_01_02_P_의원.csv";
List<Hospital> hospitalList = hospitalReadLineContext.readByLine(filename);
assertTrue(hospitalList.size()>1000);
assertTrue(hospitalList.size()>10000);
}
}
queryForObject와 Update의 차이점
update()
- SQL 연산을 통해 데이터베이스를 갱신시켜줄 때 (INSERT, DELETE, UPDATE) 사용하는 메서드
// INSERT
this.jdbcTemplate.update("insert into users(id, name, password) values(?,?,?)",
user.getId(), user.getName(), user.getPassword());
// UPDATE
this.jdbcTemplate.update("update users set name=? where password=?",
user.getName() , user.getPassword());
// DELETE
this.jdbcTemplate.update("delete from users");
queryForObject()
- SELECT를 실행했을 때 하나의 객체(Object) 결과 값이 나올 때 사용하는 메소드
RowMapper<Hospital> rowMapper = (rs, rowNum) -> {
Hospital hospital = new Hospital(
rs.getInt("id"),
rs.getString("open_service_name"),
rs.getInt("open_local_government_code"),
rs.getString("management_number"),
rs.getTimestamp("license_date").toLocalDateTime(),
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;
};
public Hospital findById(int id) throws ClassNotFoundException, SQLException {
String sql = "select * from nation_wide_hospital where id = ?";
return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}
queryForObject 변경점
- 기존 queryForObject()
- queryForObject(sql, args, rowMapprer)
/** @deprecated */
@Deprecated
@Nullable
public <T> T queryForObject(String sql, @Nullable Object[] args, RowMapper<T> rowMapper) throws DataAccessException {
List<T> results = (List)this.query((String)sql, (Object[])args, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper, 1)));
return DataAccessUtils.nullableSingleResult(results);
}
- 변경된 queryForObject()
- queryForObject(sql, rowMapprer, args)
@Nullable
public <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args) throws DataAccessException {
List<T> results = (List)this.query((String)sql, (Object[])args, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper, 1)));
return DataAccessUtils.nullableSingleResult(results);
}
파라미터의 순서가 바뀌었으며 Object[]타입의 변수를 받아 배열에 넣었으나 가변인자를 받는 방식으로 변경되었다.
어노테이션
@SpringBootApplication
@SpringBootApplicaion은 세가지 어노테이션의 역할을 수행
- @EnableAutoConfiguration
- @ComponentScan
- @SpringBootConfiguration
// Same as @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@EnableAutoConfiguration
Spring Boot의 자동 구성 메커니즘을 활성화
spring.factories안의 Configuration가 있으며, 조건에 따라 Bean을 등록
@ComponentScan
패키지 안에 있는 @Component 어노테이션을 갖고 있는 클래스를 스캔하여 @Bean으로 등록
(@Service, @RestController, @Controller 등)
@SpringBootConfiguration
컨텍스트에서 추가 빈을 등록하거나 추가 구성 클래스를 가져온다. 통합테스트에서 @Configuration을 지원하는 Spring 표준
@SpringBootTest
모든 빈들을 스캔하고, 애플리케이션 컨텍스트를 생성하여 테스트를 실행
SpringBootTest 어노테이션에는 다양한 값들을 줄 수 있다.
- value, properties: 애플리케이션 실행에 필요한 프로퍼티를 key=value 형태로 추가
- args: 애플리케이션의 arguments로 값을 전달
- classes: 애플리케이션을 로딩할 때 사용되는 컴포넌트 클래스 정의
- webEnvironment: 웹 테스트 환경을 설정할 수 있음
참조
람다식
스프링부트 어노테이션
스프링부트테스트
반응형
'회고록 > Archive' 카테고리의 다른 글
[Spring Security & JWT] 1. Security 적용 (0) | 2022.12.06 |
---|---|
retrospect: 멋쟁이 사자처럼 백앤드 스쿨 2022.11.16 회고 (0) | 2022.12.04 |
retrospect: 멋쟁이 사자처럼 백앤드 스쿨 2022.10.18 회고 (0) | 2022.12.02 |
retrospect: 멋쟁이 사자처럼 백앤드 스쿨 2022.09.30 회고 (0) | 2022.12.02 |
docs: 멋쟁이 사자처럼 백앤드 스쿨 2기 수업 일지 READ ME(2022-11-13) (7) | 2022.11.13 |