DAO 및 서비스 계층 (JPA / Hibernate + Spring)
이 질문에 이미 답변이 있습니다.
JPA / Hibernate, Spring 및 Wicket을 기반으로하는 새로운 앱을 디자인하고 있습니다. DAO와 서비스 계층의 차이점은 나에게 명확하지 않습니다. Wikipedia에 따르면 DAO는
특정 유형의 데이터베이스 또는 지속성 메커니즘에 대한 추상 인터페이스를 제공하여 데이터베이스의 세부 사항을 노출하지 않고 특정 작업을 제공하는 객체입니다.
DAO가 실제로 데이터 액세스와 관련이없는 메서드를 포함 할 수 있는지 궁금했지만 쿼리를 사용하여 실행하는 것이 훨씬 더 쉬운가요? 예를 들어 "특정 공항에서 운항하는 모든 항공사 목록을 가져 오십시오"? 서비스 계층 방법에 더 가깝다고 들리지만 서비스 계층에서 JPA EntityManager를 사용하는 것이 좋은 사례인지 확실하지 않습니까?
DAO는 단일 관련 데이터 소스에 대한 액세스를 제공해야하며 비즈니스 모델이 얼마나 복잡한 지에 따라 완전한 비즈니스 개체 또는 간단한 데이터 개체를 반환합니다. 어느 쪽이든 DAO 메서드는 데이터베이스를 다소 밀접하게 반영해야합니다.
서비스는 비즈니스 객체를 처리 할뿐만 아니라 처음부터 액세스 할 수 있도록 더 높은 수준의 인터페이스를 제공 할 수 있습니다. 서비스에서 비즈니스 객체를 가져 오면 해당 객체가 다른 데이터베이스 (및 다른 DAO)에서 생성 될 수 있으며 HTTP 요청에서 생성 된 정보로 장식 될 수 있습니다. 여러 데이터 개체를 하나의 강력한 비즈니스 개체로 변환하는 특정 비즈니스 논리가있을 수 있습니다.
일반적으로 DAO는 해당 데이터베이스 또는 비즈니스 관련 데이터 집합을 사용하려는 모든 사람이 사용할 것이라고 생각하며, 말 그대로 데이터베이스 내의 트리거, 함수 및 저장 프로 시저 외에 가장 낮은 수준의 코드입니다.
특정 질문에 대한 답변 :
DAO가 실제로 데이터 액세스와 관련이없는 메서드를 포함 할 수 있는지 궁금했지만 쿼리를 사용하여 실행하는 것이 훨씬 더 쉬운가요?
대부분의 경우 그렇지 않은 경우 서비스 계층에서 더 복잡한 비즈니스 논리, 별도의 쿼리에서 데이터 어셈블리를 원할 것입니다. 그러나 처리 속도가 염려된다면 서비스 계층은 모델의 아름다움을 깨더라도 DAO에 작업을 위임 할 수 있습니다. 이는 C ++ 프로그래머가 특정 작업의 속도를 높이기 위해 어셈블러 코드를 작성할 수있는 것과 거의 같습니다.
서비스 계층 방법에 더 가깝다고 들리지만 서비스 계층에서 JPA EntityManager를 사용하는 것이 좋은 사례인지 확실하지 않습니까?
서비스에서 엔티티 관리자를 사용하려는 경우 엔티티 관리자를 DAO로 생각하십시오. 이것이 바로 그것이 기 때문입니다. 중복 쿼리 빌드를 제거해야하는 경우 서비스 클래스에서 제거하지 말고 엔티티 관리자를 활용 한 클래스로 추출하여 DAO로 만드십시오. 사용 사례가 정말 간단하다면 서비스 계층을 완전히 건너 뛰고 엔티티 관리자 또는 컨트롤러에서 DAO를 사용할 수 있습니다. 모든 서비스가 getAirplaneById()
DAO에 호출을 전달하는 것이므로findAirplaneById()
업데이트-아래 논의와 관련하여 명확히하기 위해, 주석에서 강조된 다양한 이유로 DAO 계층이있는 대부분의 상황에서 서비스에서 엔티티 관리자를 사용하는 것이 최선의 결정이 아닐 수 있습니다. 그러나 제 생각에는 다음과 같이 완벽하게 합리적 일 것입니다.
- 서비스는 서로 다른 데이터 세트와 상호 작용해야합니다.
- 하나 이상의 데이터 세트에 이미 DAO가 있습니다.
- 서비스 클래스는 자체 DAO를 보증하지 않을만큼 간단한 지속성을 요구하는 모듈에 있습니다.
예.
//some system that contains all our customers information
class PersonDao {
findPersonBySSN( long ssn )
}
//some other system where we store pets
class PetDao {
findPetsByAreaCode()
findCatByFullName()
}
//some web portal your building has this service
class OurPortalPetLostAndFoundService {
notifyOfLocalLostPets( Person p ) {
Location l = ourPortalEntityManager.findSingle( PortalUser.class, p.getSSN() )
.getOptions().getLocation();
... use other DAO's to get contact information and pets...
}
}
한 가지는 확실합니다. 서비스 계층에서 EntityManager를 사용하는 경우 dao 계층이 필요하지 않습니다 (하나의 계층 만 구현 세부 정보를 알아야 함). 그 외에도 다른 의견이 있습니다.
- 어떤 사람들은 EntityManager가 필요한 모든 dao 기능을 노출하므로 서비스 계층에 EntityManager를 삽입합니다.
- 다른 것들은 인터페이스로 뒷받침되는 전통적인 dao 계층을 가지고 있습니다 (따라서 서비스 계층은 구현 세부 사항에 묶여 있지 않습니다).
두 번째 접근 방식은 우려 사항을 분리 할 때 더 우아하고 하나의 지속성 기술에서 다른 기술로 쉽게 전환 할 수있게 해줍니다 (새로운 기술로 dao 인터페이스를 다시 구현해야 함). 첫 번째가 더 쉽습니다.
작은 프로젝트가있는 경우 서비스 레이어에서 JPA를 사용하고 큰 프로젝트에서는 전용 DAO 레이어를 사용합니다.
Adam Bien 의이 기사 가 유용 할 수 있습니다.
전통적으로 서비스 계층과 데이터 계층 간의 계약을 정의하는 인터페이스를 작성했습니다. 그런 다음 구현을 작성하면 DAO가됩니다.
귀하의 예로 돌아갑니다. airport_id 및 airline_id를 포함하는 테이블을 사용하여 Airport와 Airline 간의 관계가 다 대다라고 가정하면 인터페이스가있을 수 있습니다.
public interface AirportDAO
{
public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports);
}
..and you might provide a Hibernate implementation of this;
public class HibernateAirportDAO implements AirportDAO
{
public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports)
{
//implementation here using EntityManager.
}
}
You could also look into having a List on your Airline entity and defining the relationship with a @ManyToMany JPA annotation. This would remove the necessity to have this particular DAO method altogether.
You might also want to look into the Abstract Factory pattern for writing DAO factories. For example;
public abstract class DAOFactory
{
private static HibernateDAOFactory hdf = new HibernateDAOFactory();
public abstract AirportDAO getAirlineDAO();
public static DAOFactory getFactory()
{
//return a concrete implementation here, which implementation you
//return might depend on some application configuration settings.
}
}
public class HibernateDAOFactory extends DAOFactory
{
private static EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
public static EntityManager getEM()
{
return emFactory.createEntityManager();
}
public AirportDAO getAirportDAO()
{
return new HibernateAirportDAO();
}
}
This pattern allows your HibernateDAOFactory to hold a single EMF and supply individual DAO instances with EMs. If you don't want to go down the fatory route then Spring is great at handling DAO instances for you with dependancy injection.
Edit: Clarified a couple of assumptions.
Dao is a data access object. It does storing/updating/selecting entities on the database. The entity manager object is used for that (at least in open jpa). You can also run query's with this entity manager. It's no sql but JPQL (Java persistence query language).
Simple example:
emf = Persistence.createEntityManagerFactory("localDB");
em = emf.createEntityManager();
Query q = em.createQuery("select u from Users as u where u.username = :username", Users.class);
q.setParameter("username", username);
List<Users> results = q.getResultList();
em.close();
emf.close();
참고URL : https://stackoverflow.com/questions/3882108/dao-and-service-layers-jpa-hibernate-spring
'Program Tip' 카테고리의 다른 글
Interface Builder가 drawRect를 재정의하지 않는 IBDesignable 뷰를 렌더링하는 방법이 있습니까? (0) | 2020.11.29 |
---|---|
Lua 패턴 매칭과 정규 표현식 (0) | 2020.11.28 |
'this'는 JavaScript 클래스 메서드에서 정의되지 않았습니다. (0) | 2020.11.28 |
Java에서 패키지 개인 클래스의 장단점? (0) | 2020.11.28 |
연속적인 JSON 스트림 처리 (0) | 2020.11.28 |