5.1 데이터베이스란?
5.1.1 데이터베이스 관리자, DBMS
- 데이터베이스를 관리하기 위한 소프트웨어(Database Management System)
- 관계형, 객체-관계형, 도큐먼트형, 비관계형 등으로 분류.
<관계형 DBMS - RDBMS>
- 관계형 모델을 기반 (테이블 형태로 이루어진 데이터 저장소)
- 각 행은 고유 키(ID)를 가지고 있음
- (ex. H2, MySQL 등 ...)
❗️꼭 알아야 할 데이터베이스 용어
1. 테이블
2. 행
3. 열
4. 기본키
5. 쿼리
5.2 ORM이란?
- ORM(object Relational Mapping)은 자바의 객체와 데이터를 연결하는 프로그래밍 기법.
- 자바 언어로만 데이터베이스를 다룰 수 있게 한다.
<ORM의 장점과 단점> [장점] 1. SQL을 직접 작성하지 않고 사용하는 언어로 데이터베이스에 접근할 수 있다. 2. 객체지향적으로 코드를 작성할 수 있기 때문에 비즈니스 로직에만 집중 가능하다. 3. 데이터베이스 시스템에 대한 종속성이 줄어든다. 4. 매핑하는 정보가 명확하기 대문에 ERD에 대한 의존도를 낮출 수 있고, 유지보수할 때 유리하다. [단점] 1. 프로젝트의 복잡성이 커질수록 사용 난이도가 올라간다. 2. 복잡하고 무거운 쿼리는 ORM으로 해결이 불가능한 경우가 있다. |
5.3 JPA와 하이버네이트
- ORM의 종류
- 자바에서는 JPA(Java Persistence API)가 표준 -> 관계형 데이터베이스 인터페이스 (내부적으로는 JDBC API를 사용하고 있음)
- JPA는 인터페이스이므로 실제 사용을 위해서는 ORM 프레임 워크를 추가로 사용해야 한다.
JPA : 자바 객체와 데이터베이스를 연결해 관리 하이버네이트 : JPA의 인터페이스를 구현 (내부적으로는 JDBC API를 사용) |
JPA <-> 하이버네이트 <-> DB 순으로 동작 |
5.3.1 엔티티 매니저
- 엔티티(entity)
- 데이터베이스의 테이블과 매핑되는 객체(데이터 베이스의 테이블과 직접 연결된다는 것이 특징)
- 엔티티 매니저(entity manager)
- 엔티티를 관리해 데이터베이스와 어플리케이션 사이에서 객체를 생성, 수정, 삭제하는 등의 역할을 함.
- 엔티티 팩토리 (entity manager factory)
- 엔티티 매니저를 만드는 곳.
- 스프링 부트에서는 엔티티 매니저 팩토리를 직접 만들지 않고, 내부에서 애너테이션(@Persistence Context 또는 @Autowired) 애너테이션을 통해 엔티티 매니저를 관리함.
@PersistenceContext
EntityManager em; // 프록시 엔티티 매니저. 필요할 때 진짜 엔티티 매니저 호출
// 스프링 부트는 기본적으로 빈을 하나만 생성해서 공유하기 때문에, 동시성 문제 발생 X
// 따라서 실제로는 엔티티 매니저가 아니지만 실제 엔티티매니저 연결하는 역할을 하는 프록시(가짜)엔티티 매니저를 사용함
// 필요할 때 데이터베이스 트랜잭션과 관련된 실제 엔티티 매니저를 호출
// 즉, 엔티티 매니저는 Spring Data JPA에서 관리하므로 직접 생성 및 관리를 할 필요가 없음.
5.3.2 영속성 컨텍스트
- 엔티티를 관리하는 가상의 공간 (이것을 사용하여 데이터베이스에서 효과적으로 데이터를 가져오고, 엔티티를 편하게 사용 가능.)
<영속성 컨텍스트의 특징 4가지>
- 1차 캐시 : DB와 애플리케이션 사이에 캐시를 가지고 있어서 빠르게 처리 가능
- 쓰기 지연 : 쿼리를 모았다가 트랜잭션을 커밋하면 한 번에 실행
- 변경 감지 : 1차 캐시의 엔티티와 현재 엔티티의 값을 비교해서 자동으로 DB에 반영
- 지연 로딩 : 바로 애플리케이션에 로딩하는 것이 아니라 필요할 때 쿼리를 통해 데이터를 조회
-> DB의 접근을 최소화하여 성능을 높이는 방법들
5.3.3 엔티티의 상태
- 분리(detached) : 영속성 컨텍스트가 관리하고 있지 않은 상태
- 관리(managed) : 영속성 컨텍스트가 관리하고 있는 상태
- 비영속(transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태
- 삭제(removed) : 삭제된 상태
public class EntityManagerTest {
@Autowired
EntityManager em;
public void example() {
// 1. 엔티티 매니저가 엔티티를 관리하지 않는 상태 (비영속 상태)
Member member = new Member(1L, "이경수");
// 2. 엔티티가 관리하는 상태 (관리 상태)
em.persist(member);
// 3. 엔티티 객체가 분리된 상태 (분리 상태)
em.detach(member);
// 4. 엔티티 객체가 삭제된 상태 (삭제 상태)
em.remove(member);
}
}
5.4. 스프링 데이터와 스프링 데이터 JPA
- 스프링 데이터
- 데이터베이스 사용 기능을 클래스 레벨에서 추상화
- 페이징 처리, 메서드 이름으로 자동 빌드 등...
5.4.1 스프링 데이터 JPA
- 스프링 데이터의 공통적인 기능에서 JPA의 유용한 기술이 추가된 기술
// 메서드 호출로 엔티티 상태 변경 예시 코드
@PersistencContext
EntityManager em;
public void join() {
// 기존에 엔티티 상태를 바꾸는 방법(메서드 호출을 해서 상태 변경)
Member member = new Member(1L, "홍길동");
em.persist(member);
}
// 기본 CRUD 메서드를 사용하기 위한 JpaRepository 상속 예
public interface MemberRepository extends JpaRepository<Member, Long> {}
5.4.2 스프링 데이터 JPA에서 제공하는 메서드 사용해보기
package me.kyungsoolee.springbootdeveloper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class MemberService {
@Autowired
MemberRepository memberRepository;
public void test() {
// 1. 생성(Create)
memberRepository.save(new Member(1L, "A"));
// 2. 조회(Read)
Optional<Member> member = memberRepository.findById(1L); // 단건 조회
List<Member> allMembers = memberRepository.findAll(); // 전체 조회
// 3. 삭제(Delete)
memberRepository.deleteById(1L);
}
}
5.5 예제 코드 살펴보기
package me.kyungsoolee.springbootdeveloper;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity // 1. 엔티티로 지정
/*
* @Entity(name = "member_list") // 'member_list'이라는 이름을 가진 테이블과 매핑
* */
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 2. 기본 생성자
@AllArgsConstructor
public class Member {
@Id // 3. id 필드를 기본키로 지정
@GeneratedValue(strategy = GenerationType.IDENTITY) // 4. 기본키 자동으로 1씩 증가
@Column(name = "id", updatable = false)
private Long id; // DB 테이블의 'id' 컬럼과 매칭
@Column(name = "name", nullable = false) // 5. name이라는 not null 컬럼과 매핑
private String name; // DB 테이블의 'name' 컬럼과 매칭
}
- 접근 제어자는 public 또는 protected여야 한다.
<자동키 생성 설정 방식>
- AUTO : 선택한 데이터베이스 방언(dialect)에 따라 방식을 자동으로 선택(기본값)
- IDENTITY : 기본 키 생성을 데이터베이스에 위임(=AUTO_INCREMENT)
- SEQUENCE : 데이터베이스 시퀀스를 사용해서 기본 키를 할당하는 방법. 오라클에서 주로 사용
- TABLE : 키 생성 테이블 사용
<@Column 애너테이션의 속성>
- name : 필드와 매핑할 컬럼 이름. 설정하지 않으면 필드 이름으로 지정
- nullable : 컬럼의 null 허용 여부. 설정하지 않으면 true(nullable)
- unique : 컬럼의 유일한 값(unique)여부. 설정하지 않으면 false(non unique)
- columnDefinition : 컬럼 정보 설정. default값을 줄 수도 있음
<궁금한 내용> 사용자 <-> 리포지토리 <-> DB <-> 엔티티?.... 리포지토리랑 엔티티?...의 관계?... 잘 모르겠음... 구조에 대한 생각을 좀 더 적립하고 가야될 듯. |
<5장 핵심 요약> 1. ORM : 객체와 데이터베이스를 연결하는 프로그래밍 기법 2. JPA : 자바에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스 3. 하이버네이트 : JPA의 구현체 중 대표적인 구현체. 자바를 위한 ORM 프레임 4. 스프링 데이터 JPA : JPA를 쓰기 편하게 만들어 놓은 모듈 |
'Spring boot > 스프링 부트 3 백엔드 개발자 되기(자바편)' 카테고리의 다른 글
[8장] 스프링 시큐리티로 로그인/로그아웃, 회원 가입 구현하기 (0) | 2023.07.25 |
---|---|
[6장] 블로그 기획하고 API 만들기(2) (0) | 2023.07.25 |
[4장] 스프링 부트 3와 테스트 (0) | 2023.07.25 |
[3장] 스프링 부트3 구조 이해하기 (0) | 2023.07.25 |
[2장] 스프링 부트 3 시작하기(2) - 스프링 부트 3 예제 만들기 (0) | 2023.07.25 |