스프링 데이터 JPA를 사용하는 경우는 별도의 구현 클래스를 만들지 않고 인터페이스만 정의함으로써 기능을 사용할 수 있다. 스프링 부트가 내부적으로 인터페이스에 대한 구현 객체를 자동으로 생성해준다. 또한 JPA를 이용해서 데이터베이스를 연동하기 위해서 사용했었던 EntityManagerFactory, EntityManager, EntityTransaction 같은 객체도 필요 없다.
이 모든 객체들의 생성과 활용이 스프링 데이터 JPA 에서는 내부적으로 처리되기 때문이다.
JPA에서는 엔티티는 테이블에 대응하는 하나의 클래스라고 생각하면 된다
spring-boot-starter-data-jpa 의존성을 추가하고 @Entity 어노테이션을 붙이면 테이블과 자바 클래스가 매핑이 된다.
그래서 JPA에서 '하나의 엔티티 타입을 생성한다'라는 의미는 '하나의 클래스'를 작성한다는 의미가 된다.
엔티티라는 용어는 때로는 클래스를 의미하는 경우도 있고, 클래스에 의해 생성된 인스턴스를 의미하는 경우가 있다.
정확히 얘기하자면, 엔티티 클래스와 엔티티 인스턴스 혹은 엔티티 객체라는 표현이 정확하다.
어노테이션으로 엔티티 클래스를 스캔할 곳을 지정하는데 사용한다.
메인 어플리케이션 패키지 내에 엔티티 클래스가 없는 경우 어노테이션을 사용해서 패키지밖에 존재하는
엔티티를 지정할 수 있다.
기본적으로 @EnableAutoConfiguration 어노테이션에 의해서 지정한 곳에서 엔티티를 스캔한다.
스프링 데이터 JPA를 사용하며 CrudRepository의 findById 메서드 리턴 타입인 Optional 클래스에 처음 접하게 되었다. Optional은 Java 8에 추가된 새로운 API로 이전에 하던 '고통스러운 null 처리'를 '잘' 다룰 수 있게 도와주는 클래스라고 한다.
Optional<T> optional
Optional<T> findById(ID id)
CrudRepository의 findById는 Entity의 id로 검색을 해서, Optional<T>
를 리턴 타입으로 반환하는 메서드이다. 따라서 다음과 같이 isPresent() 를 이용하여 Optional 내부에 객체가 들어있는지 확인한 후에 get()을 이용해 반환된 객체를 꺼내 쓸 수 있다.
Optional<ExEntity> optional = exRepsoitory.findById(id);
if(optional.isPresent()) {
ExEntity exEntity = optional.get();
} else {
throw new Exception();
}
orElse(...)에서 ...는 Optional에 값이 있든 없든 무조건 실행된다.
따라서 ...가 새로운 객체를 생성하거나 새로운 연산을 수행하는 경우에는 orElse( ) 대신 orElseGet( )을 써야한다.
Optional에 값이 없으면 orElse( )의 인자로서 실행된 값이 반환되므로 실행한 의미가 있지만, Optional에 값이 있으면 orElse( )의 인자로서 실행된 값이 무시되고 버려진다. 따라서 orElse(...)는 ...가 새 객체 생성이나 새로운 연산을 유발하지 않고 이미 생성되었거나 이미 계산된 값일 때만 사용해야 한다.
orElseGet(...)에서 ...는 Optional에 값이 없을 때만 실행된다.
따라서 Optional에 값이 없을 때만 새 객체를 생성하거나 새 연산을 수행하므로 불필요한 오버헤드가 없다.
추가
리엑트는 순수 자바스크립트가 아니다 => 베이스가 자바스크립트일 뿐이다
함수 뒤에 ()를 붙이면 새로고침 하자마자 무조건 실행된다.
=> 해결하려면 함수로 한번 묶어준다.
=> 값을 넘길때는 함수 ex) () => 함수(값)
https://ko.reactjs.org/docs/hooks-state.html
Hook은 React 16.8버전에 새로 추가되었습니다.
Hook은 클래스 컴포넌트를 작성하지 않아도 state와 같은 특징들을 사용할 수 있습니다.
Hook의 개요
함수형 컴포넌트는 렌더링할때마다 내부의 것들을 기억하지 못한다.
다시 생성, 초기화 해야한다. (변수, 함수 등)
내부의 것들을 유지하기 위해서 hook이 등장했다 - useXXX
useState
import React, { useState } from 'react';
const Test03 = () => {
const [name, setName] = useState('홍길동')
const [age, setAge] = useState(25)
const [color, setColor] = useState('cyan')
const onName = () => {
setName('코난')
}
const onAge = (num) => {
setAge(num)
}
return (
<div>
<h2 style={{background: color}}>
이름 : { name } / 나이 : { age }
</h2>
<p>
<button onClick={onName}>코난으로 이름을 변경</button>
<br/>
<button onClick={() => onAge(30)}>30살로 변경</button>
<br/>
<button onClick={() => setAge(35)}>35살로 변경</button>
<br/>
<button onClick={() => setColor('yellow')}>노란색으로 변경</button>
</p>
</div>
);
};
export default Test03;