본격적으로 JPA를 시작하기에 앞서, 개발환경 세팅이 필요하다.
소스코드는 김영한 저자님 깃허브를 참고하여 인텔리제이-메이븐으로 작성했다.
https://github.com/holyeye/jpabook
GitHub - holyeye/jpabook
Contribute to holyeye/jpabook development by creating an account on GitHub.
github.com
*25년 1월을 기준으로 약 10년전에 집필하신 책이기 때문에 코드의 버전이 맞지 않아서 코드를 수정했다.
H2 데이터베이스 설치 링크
https://www.h2database.com/html/main.html
H2 Database Engine
H2 Database Engine Welcome to H2, the Java SQL database. The main features of H2 are: Very fast, open source, JDBC API Embedded and server modes; in-memory databases Browser based Console application Small footprint: around 2.5 MB jar file size Supp
www.h2database.com
자신의 운영체제에 맞는 파일을 다운받고, H2가 설치된 경로의 파일로 접근하여
윈도우의 경우 h2.bat 또는 h2w.bat 파일을 실행하면 H2 콘솔 페이지에 접근할 수 있다.
*H2 데이터베이스는 JVM 메모리 안에서 실행되는 임베디드 모드와
실제 데이터베이스처럼 별도의 서버를 띄워서 동작하는 서버 모드가 있는데,
서버모드로 연결하면된다.
최종 프로젝트 구조는 다음과 같다.
Member 클래스 생성
package hellojpa;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
public class Member {
@Id
private Long id;
@Column(name = "NAME")
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
매핑 정보 | 회원 객체 | 회원 테이블 |
기본키 | id | Id |
필드와 컬럼 | name | NAME |
각 어노테이션 설명
@Entity
- 테이블과 매핑한다고 JPA에 알려준다.
- @Entity가 사용된 클래스를 "엔티티 클래스"라고 한다.
@Table
- 엔티티 클래스와 매핑할 테이블 정보를 알려준다.
- "name" 속성을 사용해서 Member엔티티를 MEMBER테이블에 매핑
*어노테이션을 생략하면 "클래스 이름"을 그대로 테이블 이름으로 매핑
@Id
- 엔티티 클래스의 필드를 테이블의 기본 키(Primary Key)에 매핑
- 엔티티의 id 필드를 테이블의 ID 기본 키 컬럼에 매핑
- @Id가 사용된 필드를 "식별자 필드"라고 한다.
@Column
- 필드를 컬럼에 매핑한다.
- "name 속성"을 사용해서 Member 엔티티의 name 필드를 테이블의 NAME 컬럼에 매핑
매핑 정보가 없는 필드
- 매핑 어노테이션을 생략하면 필드명을 사용해서 컬럼명으로 매핑된다.
- 필드명이 'age'라면 'age'컬럼으로 매핑
데이터베이스 방언
JPA는 특정 데이터베이스에 종속적이지 않은 기술.
다른 데이터베이스로 손쉽게 교체할 수 있다.
데이터베이스마다 차이점
- 데이터 타입
- 다른 함수명
- 페이징 처리
SQL 표준을 지키지 않거나 특정 데이터베이스만의 고유한 기능을
JPA에서는 "Dialect(방언)"이라고 한다.
어플리케이션 개발
작성한 코드는 아래와 같다.
public class JpaMain {
public static void main(String[] args) {
// 엔티티매니저팩토리 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
// 엔티티매니저 생성
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); //트랜잭션 시작
// 정석 코드 -> try-catch문
try { // try-catch문 안에 작성한다. 정상적일땐 커밋, 문제가 생겼을 땐 rollback, 작업이 다 끝나면 em close,
// 전체 애플리케이션이 끝나면 emf close
// 삽입
Member member = new Member();
member.setId(1L);
member.setName("HelloA");
member.setId(2L);
member.setName("HelloB");
// 등록
em.persist(member);
// 조회
Member findMember = em.find(Member.class,2L);
System.out.println("findMember.id = " + findMember.getId());
System.out.println("findMember.name = " + findMember.getName());
// 삭제
Member findMember = em.find(Member.class,2L); // 찾고
em.remove(findMember);
// 수정 : persist 사용할 필요가 없다.
Member findMember = em.find(Member.class,2L);
findMember.setName("HelloB");
// JPQL로 전체 회원 검색하기 : 맴버 객체를 대상으로 쿼리를 작성함
List<Member> result = em.createQuery("select m from Member as m", Member.class)
// 페이징을 하고싶다면
.setFirstResult(5)
.setMaxResults(8)
.getResultList();
for (Member member : result) {
System.out.println("member.name = " + member.getName());
}
tx.commit();
} catch (Exception e) { // 문제가 생겼을 때, rollback
tx.rollback();
} finally { // 작업이 다 끝나면 em.close
em.close();
}
emf.close(); // 전체 애플리케이션이 끝나면 emf.close
}
}
EntityManagerFactory 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
- persistence.xml의 설정 정보를 사용해서 엔티티 매니저 팩토리 생성한다.
- Persistence 클래스 사용한다.
- Persistence 클래스 : 엔티티 매니저 팩토리를 생성해서 JPA를 사용할 수 있게 준비한다.
EntityManager 생성
EntityManager em = emf.createEntityManager();
- 엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.
- 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있기 때문에 스레드간 공유나 재사용을 하면 안된다.
종료
사용이 끝난 엔티티 매니저는 반드시 종료
em.close(); // 엔티티 매니저 종료
어플리케이션을 종료할 때 엔티티 매니저 팩토리도 종료
emf.close(); // 엔티티 매니저 팩토리 종료
JPQL
하나 이상의 회원 목록 조회하는 코드
//목록 조회
List<Member> members = em.createQuery("select m from Member m", Member.class)
.getResultList();
System.out.println("members.size=" + members.size());
문제점 - 검색 쿼리
JPA는 엔티티 중심으로 개발을 하기 때문에 엔티티 대상으로 검색해야 한다.
그러나 테이블이 아닌 엔티티 객체를 대상으로 검색하려면 데이터베이스 모든 데이터를 어플리케이션으로 불러와 엔티티 객체로 변경해서 검색해야 함.
해결
JPA는 JPQL(Java Persistence Query Language)로 해결할 수 있다.
JPQL 과 SQL 차이
JPQL : 엔티티 객체를 대상으로 쿼리
SQL : 데이터베이스 테이블을 대상으로 쿼리
'Study' 카테고리의 다른 글
[소프트웨어 공학] 애자일(Agile) 방법론 (0) | 2025.03.03 |
---|---|
[JPA] 컬렉션과 연관 매핑 (0) | 2025.02.24 |
[점프 투 스프링 부트3] 프로젝트 구조 _ 게시판 프로젝트 (0) | 2025.02.24 |
[점프 투 스프링 부트3] 웹 서비스의 동작 이해와 URL 매핑 (0) | 2025.02.17 |
[자바 ORM 표준 JPA 프로그래밍] 1장. JPA 소개 (0) | 2025.02.02 |