Spring Framework

교과목 내용을 정리하기 위한 글입니다. 틀린 내용이 있을 수 있으니 참고하세요
JPA란?
Standard API for Object-to-Relational Mapping (ORM)
- 모든 저수준(low-level) SQL 처리
- 개발자들이 객체 모델을 사용하여 프로그래밍에 집중할 수 있도록 도움
Object-To-Relational Mapping (ORM)
단순 명세
- 인터페이스 집합을 정의함
- 사용하기 위해서 구현이 필요함
- 표준 API를 사용함으로써, 공급자의 구현에 얽매이지 않음
※ JPA는 구현이 없는 명세나 인터페이스임
※ Hibernate는 JPA의 구현체임
JDBC vs JPA(Hibernate) vs Spring Data JPA
JPA
- JDBC: Low-Level Database Access
- JPA: Java Persistence API를 나타내는 기술적 명세, 관계형 데이터베이스를 위한 인터페이스로 정의됨
- Hibernate: JPA의 구현체
- Spring Data JPA: JPA를 쉽게 하용하도록 만든 모듈
JPA
Entity Class
데이터베이스 테이블에 매핑되는 자바 클래스
Entity Class
최소 조건
- @Entity 주석 필수
- public 혹은 protected 기본 생성자 필수 (다른 생성자도 가질 수 있음)
Java Annotations
- 1단계: 클래스를 데이터베이스 테이블에 매핑하기
- 2단계: 필드를 데이터베이스 컬럼에 매핑하기
@Table
Map class to database table
- 선택사항으로 없으면 클래스 이름으로 자동 설정됨
@Column
Map fields to database columns
- 선택사항으로 없으면 필드 이름으로 자동 설정됨
@Id, @GeneratedValue
Primary Key
Primary Key
- 각 행을 고유하게 실벽
- 반드시 고유한 값으로 NULL일 수 없음
ID Generation Strategies
타입 | 설명 |
---|---|
GenerationType.Auto | 특정 데이터베이스를 위한 적절한 전략을 선택 |
GenerationType.IDENTITY | 데이터베이스 ID 열을 사용하여 Primary Key 할당 |
GenerationType.SEQUENCE | 데이터베이스 시퀀스로 Primary Key 할당 |
GenerationType.TABLE | 기본 키의 고유성을 보장하기 위해 기본 데이터베이스 테이블을 사용하여 할당 |
Entity Manager
Entity Manager
- EntityManagerFactory : EntityManager의 객체 제공
- JPA EntityManager (interface) : 특정 애플리케이션에서 데이터베이스를 접근하기 위해 사용
EntityManager API는 영속적인 엔티티 인스턴스를 생성 및 제거하고, 기본 키로 엔티티를 찾으며, 엔티티를 대상으로 쿼리를 수행하는 데 사용됩니다.
Action | JPA Methods | Hibernate Methods |
---|---|---|
Create/Save new Entity | entityManager.persist(...) | session.save(...) |
Retrieve Entity by ID | entityManager.find(...) | session.get(...)/load(...) |
Retrieve list of Entities | entityManager.createQuery(...) | session.createQuery(...) |
Save or Update Entity | entityManager.merge(...) | session.saveOrUpdate(...) |
Delete Entity | entityManager.remove(...) | session.delete(...) |
Persistence Contetxt
Persistence Contetxt
- EntityManager 객체는 Persistence Context와 연관된다.
- Persistence Context는 Entity 객체들의 집합으로 데이터베이스에서 엔티티를 가져오거나 데이터베이스에 저장할 때 사용되는 1차 캐시
Entity Lifecycle
Entity Lifecycle
상태 | Persistence Context에 있음? | 설명 |
---|---|---|
New / Transient | ❌ 아님 | 아직 저장되지 않은 순수 객체 |
Persistent / Managed | ✅ 있음 | Persistence Context가 관리 중 |
Detached | ❌ 아님 | 한 번 저장됐지만 지금은 관리되지 않음 |
Removed | ✅ 있음 (삭제 대기 상태) | 삭제 예약된 상태. flush/commit 시 실제 삭제 |
EntityManager API
CRUD (Create, Read, Update, Delete)
@Override
public void save(Student theStudent){
entityManager.persist(theStudent);
}
@Override
public Student load(){
Student myStudent = entityManager.find(Student.class, 1);
}
※ EntityClass와 Primary Key 전달
복잡한 연산은 어떻게 할까?
JPA Query Language (JPQL)
- 객체들을 조회하기 위한 Query Language
- SQL과 비슷하지만 JPQL은 entity name과 entity fields에 기반함
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student", Student.class);
List<Student> students = theQuery.getResultList()
※ Class 이름과 Return 타입 전달
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName=`Doe`", Student.class);
List<Student> students = theQuery.getResultList()
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName=`Doe` OR firstName=`Daffy`", Student.class);
List<Student> students = theQuery.getResultList()
※ 엔티티 이름 필드 이름에 주의가 필요함
public List<Student> findByLastName(String theLastName) {
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName=:theData", Student.class);
theQuery.setParameter("theData", theLastName);
List<Student> students = theQuery.getResultList()
}
※ Query에 변수 사용 시 parameter를 설정해주어야 함
Student myStudent = entityManager.find(Student.class, 1);
theStudent.setFirstName("Scooby");
entity.merge(theStudent);
int numsRowsUpdated = entityManager.createQuery(
"UPDATE Student SET lastName=`Tester`")
.executeUpdate();
Student myStudent = entityManager.find(Student.class, 1);
entity.remove(theStudent);
int numsRowsUpdated = entityManager.createQuery(
"DELETE FROM Student WHERE lastNAme=`Smith`")
.executeUpdate();
int numsRowsDeleted = entityManager.createQuery(
"DELETE FROM Student")
.executeUpdate();
DAO (Data Access Object)
- 데이터베이스를 규격화 함
- JPA Entity Manager가 필요함 (조회, 저장을 위한 기본 컴포넌트)
Data Access Object
JPA Entity Manager
- JPA Entity Manager는 데이터 소스가 필요함
- 데이터 소스는 데이터베이스 연결 정보를 정의함
- JPA Entity Manager를 Student DAO에 자동 주입하거나 주입할 수 있음
@Repository
@Transactional
public class StudentDao {
@PersistenceContext
private EntityManager entityManager;
public Student findById(Integer id) {
return entityManager.find(Student.class, id);
}
public List<Student> findAll() {
// create query
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student", Student.class);
// return query results
return theQuery.getResultList();
}
public void save(Student theStudent) {
entityManager.persist(theStudent);
}
public void update(Student theStudent) {
entityManager.merge(theStudent);
}
public void delete(Integer id) {
// retrieve the student
Student theStudent = entityManager.find(Student.class, id);
// delete the student
entityManager.remove(theStudent);
}
}
Spring @Transactional
- 자동으로 JPA 코드에 대한 트랜잭션을 시작하고 종료함
- 코드를 명시적으로 작성할 필요가 없음
- 사용자 모르게 처리됨