Spring

Spring Boot - DAO

728x90

참조한 강의 : 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(11NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45DEFAULT NULL,
  `last_name` varchar(45DEFAULT NULL,
  `email` varchar(45DEFAULT 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 를 추가해줘야한다

 

728x90

'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