복붙노트

[SPRING] DAO 및 서비스 계층 (JPA / Hibernate + Spring) [duplicate]

SPRING

DAO 및 서비스 계층 (JPA / Hibernate + Spring) [duplicate]

JPA / Hibernate, Spring 및 Wicket을 기반으로하는 새 앱을 설계하고 있습니다. DAO와 서비스 계층의 차이점은 분명하지 않습니다. Wikipedia에 따르면, DAO는

DAO가 실제로 데이터 액세스를 많이 할 필요가없는 메소드를 포함 할 수 있는지 궁금해했지만 쿼리를 사용하여보다 쉽게 ​​실행될 수 있습니까? 예를 들어 "특정 공항 집합을 운영하는 모든 항공사의 목록을 얻으십시오"? 더 나은 서비스 레이어 방법이 될 것 같지만 서비스 레이어에서 JPA EntityManager를 사용하는 것이 좋은 방법인지 잘 모르겠습니다.

해결법

  1. ==============================

    1.DAO는 하나의 관련 데이터 소스에 대한 액세스를 제공해야하며 비즈니스 모델의 복잡성에 따라 완전한 비즈니스 개체 또는 간단한 데이터 개체를 반환해야합니다. 어쨌든, DAO 방법은 데이터베이스를 어느 정도 밀접하게 반영해야합니다.

    DAO는 하나의 관련 데이터 소스에 대한 액세스를 제공해야하며 비즈니스 모델의 복잡성에 따라 완전한 비즈니스 개체 또는 간단한 데이터 개체를 반환해야합니다. 어쨌든, DAO 방법은 데이터베이스를 어느 정도 밀접하게 반영해야합니다.

    서비스는 비즈니스 오브젝트를 처리 할뿐만 아니라 처음 액세스 할 수 있도록 더 높은 수준의 인터페이스를 제공 할 수 있습니다. 서비스에서 비즈니스 개체를 얻으면 해당 개체는 다른 데이터베이스 (및 다른 DAO)에서 만들어 질 수 있으며 HTTP 요청으로 만들어진 정보로 장식 될 수 있습니다. 여러 데이터 오브젝트를 하나의 강력한 비즈니스 오브젝트로 변환하는 특정 비즈니스 로직을 가질 수 있습니다.

    필자는 일반적으로 데이터베이스를 사용하려는 사람이나 비즈니스 관련 데이터 집합을 사용하는 사람이 DAO를 만들 것이라고 생각합니다. 이는 데이터베이스 내에서 트리거, 함수 및 저장 프로 시저 외에 문자 그대로 가장 낮은 수준의 코드입니다.

    특정 질문에 대한 답변 :

    대부분의 경우, 서비스 계층에 복잡한 비즈니스 로직이 필요하고 별도의 쿼리에서 데이터를 조합해야합니다. 그러나 서비스 속도는 C ++ 프로그래머가 어셈블러 코드를 작성하여 특정 동작을 가속화하는 것과 거의 같은 방식으로 모델의 아름다움을 깨뜨리지 만 DAO에 작업을 위임 할 수 있습니다.

    서비스에서 엔티티 관리자를 사용하려면 엔티티 관리자를 DAO로 생각하십시오. 왜냐하면 그것이 정확히 무엇이기 때문입니다. 중복 쿼리를 제거해야하는 경우 서비스 클래스에서이를 수행하지 말고 엔티티 관리자를 활용 한 클래스로 추출하여 DAO로 만듭니다. 당신의 유스 케이스가 정말로 단순하다면 서비스 계층 전체를 건너 뛰고 엔티티 관리자 또는 컨트롤러에서 DAO를 사용할 수 있습니다. 왜냐하면 모든 서비스가 DAO의 findAirplaneById ()에 대한 getAirplaneById () 호출을 전달할 것이기 때문입니다.

    업데이트 - 아래 논의와 관련하여 명확히하기 위해, 서비스에서 엔티티 관리자를 사용하는 것은 주석에 강조 표시된 다양한 이유로 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...
       }
    }
    
  2. ==============================

    2.한 가지는 확실합니다. 서비스 계층에서 EntityManager를 사용하는 경우 dao 계층은 필요하지 않습니다 (단 하나의 계층 만 구현 세부 사항을 알아야합니다). 그 외에도 다른 의견이 있습니다.

    한 가지는 확실합니다. 서비스 계층에서 EntityManager를 사용하는 경우 dao 계층은 필요하지 않습니다 (단 하나의 계층 만 구현 세부 사항을 알아야합니다). 그 외에도 다른 의견이 있습니다.

    두 번째 접근법은 관심사를 분리 할 때 더욱 우아하며 한 지속성 기술에서 다른 기술로 쉽게 전환 할 수 있습니다 (새로운 기술로 DAO 인터페이스를 다시 구현해야 함). 변경됩니다, 첫 번째 쉽습니다.

    당신이 작은 프로젝트를 가지고 있다면, 서비스 레이어에서 JPA를 사용 하겠지만 큰 프로젝트에서는 전용 DAO 레이어를 사용한다고 말하고 싶습니다.

  3. ==============================

    3.Adam Bien의이 기사가 유용 할 수 있습니다.

    Adam Bien의이 기사가 유용 할 수 있습니다.

  4. ==============================

    4.전통적으로 서비스 레이어와 데이터 레이어 사이의 계약을 정의하는 인터페이스를 작성할 수 있습니다. 그런 다음 구현을 작성하고 이들은 DAO입니다.

    전통적으로 서비스 레이어와 데이터 레이어 사이의 계약을 정의하는 인터페이스를 작성할 수 있습니다. 그런 다음 구현을 작성하고 이들은 DAO입니다.

    당신의 본보기로 돌아 가라. 공항과 항공사 간의 관계가 airport_id와 airline_id가 들어있는 테이블을 가지고 있다고 가정하면 인터페이스가있을 수 있습니다.

    public interface AirportDAO
    {
       public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports);
    }
    

    .. 그리고 당신은 이것에 대한 Hibernate 구현을 제공 할 수도있다;

    public class HibernateAirportDAO implements AirportDAO
    {
       public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports)
       {
          //implementation here using EntityManager.
       }
    }
    

    Airline 엔티티에 List가 있고 @ManyToMany JPA 주석과의 관계를 정의 할 수도 있습니다. 이것은이 DAO 메소드를 모두 가지고 있어야 할 필요성을 제거합니다.

    DAO 팩토리를 작성하기위한 추상 팩토리 패턴을 살펴볼 수도 있습니다. 예를 들어;

    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();
       }
    }
    

    이 패턴은 당신의 HibernateDAOFactory가 단일 EMF를 유지하고 개별 DAO 인스턴스에 EM을 제공 할 수있게 해준다. 만약 당신이 fatory 경로를 내려가고 싶지 않다면, Spring은 dependancy injection을 사용하여 DAO 인스턴스를 다루는데 아주 좋습니다.

    편집 : 몇 가지 가정을 명확히했습니다.

  5. ==============================

    5.Dao는 데이터 액세스 개체입니다. 데이터베이스에서 엔티티를 저장 / 업데이트 / 선택합니다. 엔티티 관리자 개체가 사용됩니다 (적어도 열린 jpa에서). 이 엔티티 관리자로 질의를 실행할 수도 있습니다. SQL은 아니지만 JPQL (Java Persistence Query Language)입니다.

    Dao는 데이터 액세스 개체입니다. 데이터베이스에서 엔티티를 저장 / 업데이트 / 선택합니다. 엔티티 관리자 개체가 사용됩니다 (적어도 열린 jpa에서). 이 엔티티 관리자로 질의를 실행할 수도 있습니다. SQL은 아니지만 JPQL (Java Persistence Query Language)입니다.

    간단한 예 :

    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();
    
  6. from https://stackoverflow.com/questions/3882108/dao-and-service-layers-jpa-hibernate-spring by cc-by-sa and MIT license