Standard API for Object-to-Relational Mapping (ORM)
Object-To-Relational Mapping (ORM)
※ JPA는 구현이 없는 명세나 인터페이스임
※ Hibernate는 JPA의 구현체임
JPA
JPA
데이터베이스 테이블에 매핑되는 자바 클래스
Entity Class
Map class to database table
Map fields to database columns
Primary Key
타입 | 설명 |
---|---|
GenerationType.Auto | 특정 데이터베이스를 위한 적절한 전략을 선택 |
GenerationType.IDENTITY | 데이터베이스 ID 열을 사용하여 Primary Key 할당 |
GenerationType.SEQUENCE | 데이터베이스 시퀀스로 Primary Key 할당 |
GenerationType.TABLE | 기본 키의 고유성을 보장하기 위해 기본 데이터베이스 테이블을 사용하여 할당 |
Entity Manager
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
Entity Lifecycle
상태 | Persistence Context에 있음? | 설명 |
---|---|---|
New / Transient | ❌ 아님 | 아직 저장되지 않은 순수 객체 |
Persistent / Managed | ✅ 있음 | Persistence Context가 관리 중 |
Detached | ❌ 아님 | 한 번 저장됐지만 지금은 관리되지 않음 |
Removed | ✅ 있음 (삭제 대기 상태) | 삭제 예약된 상태. flush/commit 시 실제 삭제 |
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 전달
복잡한 연산은 어떻게 할까?
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();
Data Access Object
JPA Entity Manager
@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);
}
}