참조한 강의 : www.udemy.com/course/spring-hibernate-tutorial/
- DAO
: DAO 는 Data Access Object 의 약자로, 레이어드 아키텍쳐에서 Persistence Layer 에 위치하고 있으며, Spring 이 DB 에 접근하기 위해 사용되는 객체이다.
이전 포스팅에서는 Spring Framework 를 이용해서 DAO 를 만들때, Hibernate ORM 을 이용했지만,
Spring Boot 에는 DAO 를 만들기 위한 방법이 3가지가 존재한다
1. 기존처럼 Hibernate API 를 사용하는 경우
2. 표준 JPA API 를 이용하는 경우
3. Spring Data JPA 를 이용하는 경우
이 포스팅에서는 이 세가지의 방법에 대해 알아본다
- 1. Hibernate API
: Hibernate 를 이용하는 방법은 사실 이전 포스팅에서 다뤘던 것 처럼 똑같이 Hibernate ORM 을 이용해서 DAO 를 정의하면 된다.
예시를 하나 들어보자
DB 에 아주 간단하게 다음과 같이 하나의 테이블만 있다고 치고 SQL 문을 작성해준다
- sql
CREATE TABLE `employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) DEFAULT NULL,
`last_name` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO `employee` VALUES
(1,'Leslie','Andrews','leslie@luv2code.com'),
(2,'Emma','Baumgarten','emma@luv2code.com'),
(3,'Avani','Gupta','avani@luv2code.com'),
(4,'Yuri','Petrov','yuri@luv2code.com'),
(5,'Juan','Vega','juan@luv2code.com');
|
cs |
그리고 레이어드 아키텍쳐 구조에 맞게 작성하기 위해서
REST Controller - Service - DAO - DB 형식으로 짜보자
(Entity, Controller, Service 는 여기서 다룰 대상이 아니므로 코드 생략함)
- EmployeeDAO.java
public interface EmployeeDAO {
List<Employee> findAll();
Employee findById(int id);
void save(Employee employee);
void deleteById(int id);
}
|
cs |
- EmployeeDAOHibernateImpl.java
@Repository
public class EmployeeDAOHibernateImpl implements EmployeeDAO {
private EntityManager entityManager;
@Autowired
public EmployeeDAOHibernateImpl(EntityManager theEntityManager) {
entityManager = theEntityManager;
}
@Override
public List<Employee> findAll() {
Session session = entityManager.unwrap(Session.class);
Query<Employee> query = session.createQuery("from Employee", Employee.class);
List<Employee> employees = query.getResultList();
return employees;
}
@Override
public Employee findById(int id) {
Session session = entityManager.unwrap(Session.class);
Employee employee = session.get(Employee.class, id);
return employee;
}
@Override
public void save(Employee employee) {
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(employee);
}
@Override
public void deleteById(int id) {
Session session = entityManager.unwrap(Session.class);
Query query = session.createQuery("delete from Employee where id=:employeeId");
query.setParameter("employeeId", id);
query.executeUpdate();
}
}
|
cs |
Hibernate 를 사용하는 방식은 사실 이전에 다뤘던 포스팅에서 했던것과 똑같다 그러므로 설명 생략
(패키지가 org.hibernate.* 에 있음)
- 2. Standard JPA API
: 표준 JPA 의 API 를 이용해서 DAO 를 만든다면 아래 코드와 같이 된다
- EmployeeDAOJpaImpl.java
@Repository
public class EmployeeDAOJpaImpl implements EmployeeDAO{
private EntityManager entityManager;
@Autowired
public EmployeeDAOJpaImpl(EntityManager theEntityManager) {
entityManager = theEntityManager;
}
@Override
public List<Employee> findAll() {
Query query = entityManager.createQuery("from Employee");
return query.getResultList();
}
@Override
public Employee findById(int id) {
return entityManager.find(Employee.class, id);
}
@Override
public void save(Employee employee) {
Employee tempEmployee = entityManager.merge(employee);
employee.setId(tempEmployee.getId());
}
@Override
public void deleteById(int id) {
Query query = entityManager.createQuery("delete from Employee where id=:employeeId");
query.setParameter("employeeId", id);
query.executeUpdate();
}
}
|
cs |
표준 JPA API 를 사용할 경우 패키지가 javax.persistence.* 에 있으며
표준 JPA 를 사용하는 것의 장점은, 표준이기 때문에 어떤 특정 API 에 종속되지 않는다는 것이다
아래의 표는 표준 JPA 의 함수와 HIbernate 의 함수를 비교한것이다
- Hibernate API vs JPA API
Hibernate API | JPA API |
session.save() | entityManager.persist() |
session.get() | entityManager.find() |
session.createQuery() | entityManager.createQuery() |
session.saveOrUpdate() | entityManager.merge() |
session.delete() | entityManager.remove() |
- 3. Spring Data JPA
: 위의 두가지 DAO 생성 방식은 한가지 큰 문제점을 갖고 있다
매번 새로운 Entity 가 추가될때 마다 DAO 를 만들어줘야 한다는 것이다
Student Entity 가 만들어지면 Student DAO 가 필요하고
Professor Entity 가 만들어지면 Professor DAO 가 필요하고 .....
매번 테이블 추가될때 마다 DAO 를 짜야 한다
매번 서로 다른 DAO 를 만든다 하더라도 코드를 보면 Entity 클래스와 PK 값만 다를뿐 결국 큰 틀은 똑같다
그래서 이런 번거로움을 줄이고자 등장한게 Spring Data JPA 이며
Spring Data JPA 를 쓰려면 JpaRepository 인터페이스를 상속받아서 사용하면 된다
- EmployeRepository.java
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}
|
cs |
JpaRepository 에 들어가는 각각의 타입은 Entity Type, Primary Key Type 이 들어가면 된다
이것만 만들어주고 EmployeeRepository 에 대한 구현부는 만들지 않아도 된다
이미 JpaRepository 내부에 다 기능이 들어가 있기 때문이다.
코드의 양을 상당히 확 줄여주는 효율성이 있음을 볼 수 있다.
- 참고.1)
@Qualifier Annotation
: 하나의 인터페이스에 대해서 여러개의 구현 클래스가 Spring Bean 으로 등록된 경우,
Spring Container 가 어떤 것을 구현 클래스로 지정할지 선택하지 못하고 오류를 낼 수 있다
이때는 @Qualifier 어노테이션을 작성하여 어떤 클래스를 해당 인터페이스의 구현 클래스로 삼을 것인지 명시해야한다.
- 참고.2)
Intellij IDEA 에서 HQL 이나 JPQL 이 인식되지 않을때
이때는 File -> Project Structure -> Modules 에 가서 Hibernate 를 추가해줘야한다
'Spring' 카테고리의 다른 글
Lombok 이란? (0) | 2021.03.29 |
---|---|
Spring Boot - Spring Data REST (0) | 2021.03.25 |
Spring Boot - Overview (0) | 2021.03.22 |
Intellij 에 Spring Framework 설정하기 (0) | 2021.03.14 |
Spring REST - REST Controller (0) | 2021.03.11 |