TIL - 0518

스프링부트

알고 개발하기 (JPA)

  • 자바를 사용해서 데이터를 유지하는 기술(그 중 ORM)의 표준 스펙 : 인터페이스
    • ORM : 객체 - 테이블 레코드를 맵핑해서, 로직 처리와 데이터베이스 데이터 관리 한방에 할 수 있음, 객체지향적으로 개발할 수 있음
    • 테이블 주도 개발이 아닌 객체 주도 개발을 할 수 있음 : 비즈니스 로직에 더 신경쓰고 개발할 수 있음
    • 단점 : 쿼리를 직접 만들지않고, 메소드로 다루기때문에 성능 튜닝이 어려움, 쿼리를 직접 만들어서 실행시킬 수도 있지만 쿼리에 얽메이는 개발을 하게되므로 ORM 장점을 버리는 것
  • JPA 구현 기술 : JPA는 표준 스펙이기때문에 이를 구현하는 기술이 있어야함 - 대표적인 구현체로 Hibernate가 있음
  • JDBC와 JPA는 따로가 아님 : JDBC는 자바 어플리케이션에서 데이터베이스를 연결 - 작업할 때 표준을 정의하는 스펙이었다면, 데이터베이스 작업 처리를 쉽고 표준화 한 것이 JPA, JDBC 라는 기술 위에서 한 단계 더 추상화한 기술(데이터를 다루는 기술)
  • 관련 용어
    • Entity : 데이터베이스에서 관리하는 데이터 대상(인스턴스, OO테이블의 레코드)
    • Entity Manager : 엔티티 인스턴스를 관리하는 역할, 라이프 사이클 관리, Entity 객체가 생성되면 Persistence Context에 넣어두고 관리함
  • 엔티티 인스턴스 라이프사이클
    • new : jvm 메모리 상에만 존재하고, Persistence Context에 등록되지도, 데이터베이스 레코드로도 존재하지않은 상태
    • managed : 메모리 - 데이터베이스 모두 같은 상태로 존재, Persistence Context에도 등록되어있음
    • removed : 어디에도 존재하지않음
    • detached : PK로 조회해서 메모리 상에서 수정되고 있는 상태(데이터베이스에 기록되어있는 상태와는 다름 - 동기화 되지않은 상태 )
  • dialect : 설정한 데이터베이스에 맞춰 SQL문으로 번역해주는 기능
    • application.properties : org.hibernate.dialect.H2Dialect
  • 캐시 : 엔티티를 Select하는 쿼리를 실행하기 전 이전에 찾아온 결과가 있는지 검색함, 있다면 리턴 없으면 쿼리 실행
  • Spring-JPA : JPA 기술을 Spring에서 사용할 수 있도록 도와주는 라이브러리

Repository 테스트하기

  • 기본적인 CRUD 작업에 대한 테스트 작성하기
@RunWith(SpringRunner.class)
@SpringBootTest
public class QuestionRepositoryTest {

	@AutoWired
	private QuestionRepository questionRepo;

	@Test
	public void insert() {
		questionRepo.save(Qustion.builder().setTitle("test").setWriter("jinbro").setContent("test 입니다."));
		assertEquals(1, questionRepo.findAll().size());
	}
	
	@Test
	public void load() {
		
	}
	
	@Test
	public void update() {
	
	}
	
	@Test
	public void delete() {
		questionRepo.delete(questionRepo.getOne(1L));
	}
}
  • @Autowired : 스프링 빈 컨테이너에서 빈을 찾아서 injection 설정하는 어노테이션
  • getOne과 findById : 기능상 같은 역할을 하지만, Optional 사용 유무에 따라 코드 사용이 달라짐
    • 안전한 Null 처리를 할 수 있음 : 객체.메소드()로 분기할 수 있음

컨트롤러 테스트하기

  • 특정 컨트롤러만 찾아와서 테스트하기
    • @SpringBootTest 어노테이션을 사용하지않고 @WebMvcTest를 사용함 : @WebMvcTest의 경우 컨트롤러를 포함한 일부 종류의 컴포넌트만 스캔함, @SpringBootTest는 일반적으로 사용하는 테스트 어노테이션,풀스캔 하는 방식 - 데이터가 늘어나면 날수록 느림)
    • MockMvc 객체를 injection 설정함(@AutoWired) : 요청을 날리도록 해서 그에 대한 결과값을 비교해볼 수 있음
    • test 참고 docs
@RunWith(SpringRunner.class)
@WebMvcTest
public class ExamControllerTest {

	@AutoWired
	private MockMvc mock;
	
	@Test
    public void hello() throws Exception {
        mock.perform(get("/exam/hello")).andExpect(content().string("hello"));
    }	
}

자바

Optional

  • NullPointerException를 catch로 처리하지않고, 개발자는 Optional 객체.메소드()로 객체지향적으로 처리할 수 있도록 하는 자바8부터 지원하는 API
    • null 예외는 Optional 내부에서 처리를 함
  • method
1. [s] Optional<T> empty() : Optional 아무것도 들어있지않은 인스턴스를 생성함
2. [s] Optional<T> of(T value) : value가 들어간(instance or null) Optional 인스턴스를 생성함
3. [s] Optional<T> ofNullable(T value) : value를 넣되, value가 null이라면 empty()가 호출되는 것과 같음, null이 아니라면 value()로 호출
4. T get() : Optional 인스턴스에 value가 있다면 value 리턴, 그렇지않으면 NoSuchElementException throws
5. boolean isPresent() : Optional 인스턴스의 value가 null인지 체크함
6. void ifPresent(Consumer<? extends T> consumer) : Optional 인스턴스의 value가 null이 아니라면 consumer 함수를 적용시킬 수 있음
7. Optional<T> filter(Predicate<? extends T> predicate) : Optional 인스턴스의 value가 null이 아니라면 filter 함수를 적용시킴
8. Optional<U> map(Function<? extends T, ? extends U> function) : Optional 인스턴스의 value가 null이 아니라면 map 함수를 적용시킴
9. T orElse(T other) : Optional 인스턴스의 value가 null이 아니라면 value를 리턴, null이라면 other을 리턴함
10. T orElseGet(Supplier<? extends T> other) : Optional 인스턴스의 value가 null이 아니라면 value 리턴, Suppiler 적용 결과를 리턴함
11. T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X : Optional 인스턴스의 value가 null이 아니라면 value 리턴, null 이라면 파라미터로 전달한 익셉션이 발생함

우아한테크캠프 1차 코딩테스트

  • 처음으로 코딩테스트라는 것을 봄, 최근들어 boj를 한 문제라도 풀려고 열심히 노력했었는데 생각과 다르게 해결 못하는 문제들이 늘어가고있던 찰나에 다시 정신 차리는 계기가 되었음. 꾸준하게 풀었다면 오늘처럼 어렵지는 않았겠다 라는 생각이 들었다. 풀긴 풀었지만 확실하게 딱 풀었다는 느낌이 든 문제는 그렇게 많지는 않았다. 마음에 들게 풀고 내가 풀었다고 스스로 생각하게되려면 노력 많이 해야겠지? 오늘을 경험 삼아 정말 열심히 해야겠다. 결과는 어떻게 될지 모르겠지만 나름 많은 것을 얻어온 도전이 되었다.