n을 2~n-1로 나눴을 때 나머지가 0이 아니면 소수
2~ n/2까지 확인
2~ 루트(n)까지 확인
(Math.sqrt가 더 연산이 많기 때문에 오래걸림)
- Math.sqrt(n)
- i*i < num
에라토스테네스 체
class Solution {
public int solution(int n) {
int answer = 0;
for (int i = 2; i < n + 1; i++) {
if(isPrime3(i)) {
answer++;
}
}
return answer;
}
// 방법 1, 2, 3이 있는데 점점 시간복잡도가 줄어듬
public boolean isPrime1(int n) {
// 2부터 n미만까지 나눴을 때
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public boolean isPrime2(int n) {
// 2부터 n/2까지 나눴을 때
for (int i = 2; i <= (n / 2); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public boolean isPrime3(int n) {
// 제곱근까지 한다면 제곱근을 포함해야함
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
🔴 단, 위의 코드처럼 구현한다면, 중복되는 코드가 너무 많음
👉 Template CallBack 적용으로 중복되는 코드 삭제
interface StatementStrategy {
boolean compare(int i, int n);
}
public class TemplateCallBackIsPrime {
public boolean isPrime(int n, StatementStrategy stmt) {
for (int i = 2; stmt.compare(i, n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
TemplateCallBackIsPrime tc = new TemplateCallBackIsPrime();
// 익명 클래스 사용
System.out.println(tc.isPrime(13, new StatementStrategy() {
@Override
public boolean compare(int i, int n) {
return i < n;
}
}));
// 람다식 활용
System.out.println(tc.isPrime(13, (i, n)-> i < n));
System.out.println(tc.isPrime(17, (i, n)-> i <= n/2));
System.out.println(tc.isPrime(19, (i, n)-> i*i <= n));
}
}
@SpringBootApplication —> @ComponentScan
@Component : 어노테이션이 달린 클래스는 Bean으로 등록해줌
(@Configuration, @Bean의 역할을 하게됨)
아래 두 코드는 같은 기능
@Component public class DaoFactory { HospitalDao hospitalDao() { return new HospitalDao(new JdbcTemplate()); } }@Configuration public class DaoFactory { @Bean HospitalDao hospitalDao() { return new HospitalDao(new JdbcTemplate()); } }
@ComponentScan : @SpringBootApplication 이 붙은 클래스 이하에 있는 모든 패키지를 스캔해서 @Component가 붙어 있거나 @Configuration, @Service, @Repository 등이 붙어있는 클래스를 빈으로 등록함
@SpringBootTest : @SpringBootApplication와 다른 디렉토리에 있기 때문에 Test시 꼭 붙여줘야함
🟢 아래 두 기능 모두 원하는 Table에 오른쪽 버튼 클릭 후 사용 가능
Table 수정 전 해야할 것
Table Date Export wizard : 데이터를 외부에서 저장할 수 있도록
Table 수정
Alter Table로 수정 가능
수정 내용
구현 간 배운 점
RowMapper 매핑할때 LocalDateTime으로 가져오는 법
LocalDateTime 비교하는 방법(isEquals 방법이 더 신뢰성이 높을수도 있음 - 정확하지 않음)
👉 시간 관련해서는 비교하는 과정에서 시간의 변동이 있을 수 있기 때문에 생각대로 안되는 경우가 많음 -> 많은 연구가 필요함
코드
import com.springboot.springbootcoreguide.domain.Hospital;
import org.springframework.beans.factory.annotation.Autowired;
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;
}
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;
}
};
// List<Hostpital> -- 11만건 Hospital을 하나씩 꺼내서 add에 넣기
public void add(Hospital hospital) {
String sql = "INSERT INTO nationwide_hospitals(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)" +
" VALUES(?, ?, ?," +
" ?, ?, ?," +
" ?, ?, ?," +
" ?, ?, ?," +
" ?, ?, ?," +
" ?);"; // 16개
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());
}
public int getCount() {
String sql = "SELECT COUNT(*) FROM nationwide_hospitals";
return this.jdbcTemplate.queryForObject(sql, Integer.class);
}
public void deleteAll() {
this.jdbcTemplate.update("DELETE FROM nationwide_hospitals");
}
public Hospital findById(int id) {
String sql = "SELECT * FROM nationwide_hospitals WHERE id = ?";
return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}
}
import com.springboot.springbootcoreguide.dao.HospitalDao;
import com.springboot.springbootcoreguide.domain.Hospital;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@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; // ParserFactory의 hospitalReadLineContext로 자동 DI
@Autowired
HospitalDao hospitalDao; // HospitalDao가 왜 DI가 될까? -> @Autowired가 있으며, HospitalDao에 @Component가 붙어있음
// Component가 있으면 @Bean을 모두 붙인다.
@Test
@DisplayName("임의의 id의 정보를 잘 불러오는지")
void findById() {
hospitalDao.deleteAll();
HospitalParser hp = new HospitalParser();
Hospital hospital = hp.parse(line1);
hospitalDao.add(hospital);
Hospital selectedHospital = hospitalDao.findById(1);
assertEquals(hospital.getHospitalName(), selectedHospital.getHospitalName());
// LocalDateTime 비교하는 방법
assertTrue(hospital.getLicenseDate().isEqual(selectedHospital.getLicenseDate()));
assertEquals(hospital.getLicenseDate(), selectedHospital.getLicenseDate());
}
@Test
@DisplayName("Hospital이 insert가 잘 되는지")
void add() {
HospitalParser hp = new HospitalParser();
Hospital hospital = hp.parse(line1);
hospitalDao.add(hospital);
}
@Test
@DisplayName("getCount와 deleteAll이 잘 되는지")
void getCountAndDeleteAll() {
hospitalDao.deleteAll();
assertEquals(0, hospitalDao.getCount());
HospitalParser hp = new HospitalParser();
Hospital hospital = hp.parse(line1);
hospitalDao.add(hospital);
assertEquals(1, hospitalDao.getCount());
}
}