[LIKELION] 221101

고관운·2022년 11월 1일

회고

😄 느낀점

  • 오늘은 실습시간이 많이 남아서 여유로웠지만 남는 시간이 많았다.

😁 목표

  • 프로그래머스 알고리즘

알고리즘

소수찾기(프로그래머스)

문제

👀 문제 확인하기 👀

소수 판별 방법

  1. n을 2~n-1로 나눴을 때 나머지가 0이 아니면 소수

  2. 2~ n/2까지 확인

  3. 2~ 루트(n)까지 확인
    (Math.sqrt가 더 연산이 많기 때문에 오래걸림)
    - Math.sqrt(n)
    - i*i < num

  4. 에라토스테네스 체

1~3번 실습

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));
    }
}

Spring Boot

@SpringBootApplication & @SpringBootTest

@SpringBootApplication

@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시 꼭 붙여줘야함

@Autowired

  • ApplicationContext = Spring 에 등록된 빈을 '이름'에 맞게 DI를 해줌
    (선언시 각각 해줘야함)

Hospital Project

Table 수정

🟢 아래 두 기능 모두 원하는 Table에 오른쪽 버튼 클릭 후 사용 가능

Table 수정 전 해야할 것
Table Date Export wizard : 데이터를 외부에서 저장할 수 있도록

Table 수정
Alter Table로 수정 가능

수정 내용

  • healthcare_provider_count : tinyint -> int
  • patient_room_count : tinyint -> int
  • total_number_of_beds : tinyint -> int
  • hospital_name : varchar(20) -> varchar(50)

Hospital add, getCount, deleteAll, findById 구현

구현 간 배운 점

  1. RowMapper 매핑할때 LocalDateTime으로 가져오는 법

    • rs.getObject("license_date", LocalDateTime.class)
    • rs.getTimestamp("license_date").toLocalDateTime()
  2. LocalDateTime 비교하는 방법(isEquals 방법이 더 신뢰성이 높을수도 있음 - 정확하지 않음)

    • assertTrue(hospital.getLicenseDate().equals(selectedHospital.getLicenseDate()));
    • assertEquals(hospital.getLicenseDate(), selectedHospital.getLicenseDate());

    👉 시간 관련해서는 비교하는 과정에서 시간의 변동이 있을 수 있기 때문에 생각대로 안되는 경우가 많음 -> 많은 연구가 필요함

코드

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());
    }
}

0개의 댓글