JPA

JJ·2024년 7월 26일

backEnd

목록 보기
15/16

자바와 DB의 패러다임 차이

자바

  • 자바 객체는 계층 구조를 가진다. 객체는 필드로 다른 객체를 참조할 수 있다.
  • 두 객체가 관계가 있을때 한 객체를 필드로 갖고있는 방식
  • ex) Food, Order가 있을 경우, Order는 Food를 갖고 있다.

DB

  • 데이터베이스의 경우 id와 같은 외래키 값을 바탕으로 다른 테이블과의 관계를 나타낸다.
  • 관계형 DB는 테이블 간의 관계를 외래 키(Foreign Key)로 표현함. 두 테이블이 1:N 혹은 1:1 의 관계를 가지고있다면 한쪽이 다른쪽의 PK를 FK를 갖게됨.
  • ex) Food, FoodOrder 테이블이 있으면 FoodOrder는 Food테이블의 번호를 FK로 갖는다.

JPA

객체 관계 매핑 (ORM): 자바 객체와 데이터베이스 테이블 간의 불일치를 해결하기 위해 JPA(Java Persistence API)와 같은 ORM 도구를 사용한다.

엔티티

자바에서의 엔티티

데이터베이스의 테이블과 일대일로 매핑된다.

데이터베이스에 담을 객체

데이터베이스에서의 엔티티

데이터베이스의 테이블을 말한다.

하지만 상황에 따라 row가 될수도 테이블이 될수도 있다.

ERD

ERD
room은 accommodation id를 fk로 가져야 하고 이걸로 accommodation과 room이 일대다로 연결된다.

db와 spring boot 연결

application.properties 세팅

스프링이 이 속성을 보고 알아서 DataSource 스프링빈 등록 cf. AutoConfiguration

인텔리제이에서 mysql 세팅하기

<프로젝트의 속성>

1) DB연결

  • spring.datasource.driver-class-name=mysql 스키마 이름
  • spring.datasource.url =내 로컬 db
  • spring.datasource.username = root
  • spring.datasource.password = mysql 비밀번호

gradle 파일 세팅

[SpringBoot] JPA + MySQL 연동

maven repository에서 찾아서 gradle 파일에 속성 추가

dependencies (
	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
)

레포지토리에서 설정

[Repository.java]
@Autowired
DataSource dataSource;

DB API들의 구현체 내 주요 객체

JDBC

  • 구현체: Hikari (패키지)
  • 주요 일꾼 : DataSource

JPA

  • 구현체: hibernate (패키지)
  • 주요 일꾼: EntityManager

Spring Data JPA

JPA 영속화

Entity

영속화 되고 싶은/된 객체

@Entity

어노테이션을 클래스 위에 달아줌으로써 영속화하고 싶다는걸 알려줌

→ 영속화가 될/된 객체 공간(EntityContext)에 들어가고 싶어

EntityManager

persist(): EntityContext에 Entity를 모아둠 + 테이블에 저장

EntityContext

자바와 디비 사이에 객체를 영속화해서 디비에 넣기 전에 보관해두는 공간

자바 객체는 컨텍스트에 우선 추가돼야 테이블에 저장할 수 있음, 디비/자바에 가려면 컨텍스트를 무조건 거쳐야 한다.

[Repository.java]

EntityManager entityManager;
public Room saveRoom(Room room) {
        roomTable.put(idx++, room);
        entityManager.persist(room);
        return roomTable.get(idx - 1);
    }

[에러1]

Caused by: org.hibernate.AnnotationException: Entity 'com.example.test.room.Room' has no identifier (every '@Entity' class must declare or inherit at least one '@Id' or '@EmbeddedId' property)

[이유]

엔티티 컨텍스트에서 객체를 식별할 수 있는 아이디가 없어서

→ pk 필드값에 @Id 어노테이션을 붙여줌.

[에러2]

TransactionRequiredException 발생

[이유]

[해결]

@Transactional 어노테이션을 service method에 추가

profile
🎀👩🏻‍💻✨🐾🌷🦅

0개의 댓글