스프링 JPA

문이빈·2023년 10월 27일
0

스프링 JPA(Java Persistence API)

1. 스프링 JPA

  • 스프링에서 데이터를 처리할 수 있도록 돕는 라이브러리이다
  • 데이터베이스에 종속적인 SQL문 없이도 개발이 가능하기 때문에 개발의 생산성을 높일 수 있다
  • 기존의 JDBC 등을 이용해서 직접 구현했던 데이터베이스 관련 작업을 대신 처리해주는 추상화된 계층의 구현 스펙이다

2. Spring Boot + MySQL + JPA

스프링 데이터 JPA를 사용하는 경우는 별도의 구현 클래스를 만들지 않고 인터페이스만 정의함으로써 기능을 사용할 수 있다. 스프링 부트가 내부적으로 인터페이스에 대한 구현 객체를 자동으로 생성해준다. 또한 JPA를 이용해서 데이터베이스를 연동하기 위해서 사용했었던 EntityManagerFactory, EntityManager, EntityTransaction 같은 객체도 필요 없다.
이 모든 객체들의 생성과 활용이 스프링 데이터 JPA 에서는 내부적으로 처리되기 때문이다.

@Entity

JPA에서는 엔티티는 테이블에 대응하는 하나의 클래스라고 생각하면 된다
spring-boot-starter-data-jpa 의존성을 추가하고 @Entity 어노테이션을 붙이면 테이블과 자바 클래스가 매핑이 된다.
그래서 JPA에서 '하나의 엔티티 타입을 생성한다'라는 의미는 '하나의 클래스'를 작성한다는 의미가 된다.
엔티티라는 용어는 때로는 클래스를 의미하는 경우도 있고, 클래스에 의해 생성된 인스턴스를 의미하는 경우가 있다.
정확히 얘기하자면, 엔티티 클래스와 엔티티 인스턴스 혹은 엔티티 객체라는 표현이 정확하다.

@EntityScan

어노테이션으로 엔티티 클래스를 스캔할 곳을 지정하는데 사용한다.
메인 어플리케이션 패키지 내에 엔티티 클래스가 없는 경우 어노테이션을 사용해서 패키지밖에 존재하는
엔티티를 지정할 수 있다.
기본적으로 @EnableAutoConfiguration 어노테이션에 의해서 지정한 곳에서 엔티티를 스캔한다.

@EnableJpaRepositories

  • JpaRepository에 대한 설정정보를 자동적으로 로딩하고 이 정보를 토대로 Repository 빈을 등록하는 역할을 한다

Optional

스프링 데이터 JPA를 사용하며 CrudRepository의 findById 메서드 리턴 타입인 Optional 클래스에 처음 접하게 되었다. Optional은 Java 8에 추가된 새로운 API로 이전에 하던 '고통스러운 null 처리'를 '잘' 다룰 수 있게 도와주는 클래스라고 한다.

Optional 클래스란?

  • Optional이란 'null일 수도 있는 객체'를 감싸는 일종의 Wrapper 클래스이다.

Optional<T> optional

  • optional 변수 내부에는 null이 아닌 T 객체가 있을 수도 있고 null이 있을 수도 있다.
  • Optional 클래스는 여러 가지 API를 제공하여 null일 수도 있는 객체를 다룰 수 있도록 돕는다.
  • Optional은 값을 Wrapping하고 다시 풀고, null일 경우에는 대체하는 함수를 호출하는 등의
    오버헤드가 있으므로 성능이 저하될 수 있다. 그렇기 때문에 메소드의 반환 값이 절대 null이
    아니라면 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에 값이 없을 때만 새 객체를 생성하거나 새 연산을 수행하므로 불필요한 오버헤드가 없다.


Chapter03JPA

Chapter04JPA

추가


React

리엑트는 순수 자바스크립트가 아니다 => 베이스가 자바스크립트일 뿐이다
함수 뒤에 ()를 붙이면 새로고침 하자마자 무조건 실행된다.
=> 해결하려면 함수로 한번 묶어준다.
=> 값을 넘길때는 함수 ex) () => 함수(값)

Hook

https://ko.reactjs.org/docs/hooks-state.html

Hook은 React 16.8버전에 새로 추가되었습니다.
Hook은 클래스 컴포넌트를 작성하지 않아도 state와 같은 특징들을 사용할 수 있습니다.

Hook의 개요

함수형 컴포넌트는 렌더링할때마다 내부의 것들을 기억하지 못한다.
다시 생성, 초기화 해야한다. (변수, 함수 등)

내부의 것들을 유지하기 위해서 hook이 등장했다 - useXXX

useState

  • 값이 유동으로 변할 때
  • const [상태데이터, 상태데이터의 값을 변경해주는 함수] = React.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;

0개의 댓글