복붙노트

[SPRING] 최대 절전 모드 : 일반 DAO

SPRING

최대 절전 모드 : 일반 DAO

내 웹 응용 프로그램에는 payment_methods, tax_codes, province_codes 등과 같은 많은 서비스 테이블 / 엔티티가 있습니다.

새로운 엔티티를 추가 할 때마다 DAO를 작성해야합니다. 것은 기본적으로 모든 것이 동일하지만 유일한 차이점은 엔티티 클래스 자체입니다.

나는 Hibernate 도구가 나를 위해 코드를 자동으로 생성 할 수 있다는 것을 알고 있지만 지금은 사용할 수 없다. (왜 묻지는 마라.) 그래서 나는 Generic DAO를 생각하고있다. 그것에 관한 많은 문헌이 있지만 조각을 모아서 봄과 함께 사용할 수는 없습니다.

제 생각에는 제네릭에 관한 것입니다. 네 가지 기본 방법이 있습니다.

그리고 그게 전부입니다.

휠을 다시 발명하지 않는 것이 가장 좋은 방법입니까? 사용할 준비가 된 것이 아직 없습니까?

해결법

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

    1.여기 내 꺼야.

    여기 내 꺼야.

    @Component
    public class Dao{
    
        @Resource(name = "sessionFactory")
        private SessionFactory sessionFactory;
    
        public <T> T save(final T o){
          return (T) sessionFactory.getCurrentSession().save(o);
        }
    
    
        public void delete(final Object object){
          sessionFactory.getCurrentSession().delete(object);
        }
    
        /***/
        public <T> T get(final Class<T> type, final Long id){
          return (T) sessionFactory.getCurrentSession().get(type, id);
        }
    
        /***/
        public <T> T merge(final T o)   {
          return (T) sessionFactory.getCurrentSession().merge(o);
        }
    
        /***/
        public <T> void saveOrUpdate(final T o){
          sessionFactory.getCurrentSession().saveOrUpdate(o);
        }
    
        public <T> List<T> getAll(final Class<T> type) {
          final Session session = sessionFactory.getCurrentSession();
          final Criteria crit = session.createCriteria(type);
      return crit.list();
        }
    // and so on, you shoudl get the idea
    

    그러면 서비스 계층에서 이와 같이 액세스 할 수 있습니다.

     @Autowired
        private Dao dao;
    
       @Transactional(readOnly = true)
        public List<MyEntity> getAll() {
          return dao.getAll(MyEntity.class);
        }
    
  2. ==============================

    2.Spring Data JPA는 DAO를 생성하는 훌륭한 프로젝트입니다. 구현을하지 않고 인터페이스 만 작성하면됩니다.

    Spring Data JPA는 DAO를 생성하는 훌륭한 프로젝트입니다. 구현을하지 않고 인터페이스 만 작성하면됩니다.

    interface PaymentMethodsDao extends JpaRepository<PaymentMethods, Integer> {}
    

    이 인터페이스 (상속 된 JpaRepository를 통해)는 자동으로 다음을 제공합니다 :

    PaymentMethod save(PaymentMethod entity);
    Iterable<PaymentMethod> save(Iterable<? extends PaymentMethod> entities);
    PaymentMethod findOne(Integer id);
    boolean exists(Integer id);
    Iterable<PaymentMethod> findAll();
    long count();
    void delete(Integer id);
    void delete(PaymentMethod entity);
    void delete(Iterable<? extends PaymentMethod> entities);
    void deleteAll();
    Iterable<PaymentMethod> findAll(Sort sort);
    Page<PaymentMethod> findAll(Pageable pageable);
    List<PaymentMethod> findAll();
    List<PaymentMethod> findAll(Sort sort);
    List<PaymentMethod> save(Iterable<? extends PaymentMethods> entities);
    void flush();
    PaymentMethod saveAndFlush(PaymentMethods entity);
    void deleteInBatch(Iterable<PaymentMethods> entities);
    

    인터페이스는 강력한 유형 (제네릭)이며 자동으로 구현됩니다. 모든 엔티티에 대해 JpaRepository 를 확장하는 인터페이스를 작성하면됩니다.

    그러나 기다려라, 그 이상이있다! PaymentMethod에 이름이 있고 유효 필드가 유효하다고 가정합니다. 인터페이스에 다음 메소드를 추가하면 :

    interface PaymentMethodsDao extends JpaRepository<PaymentMethods, Integer> {
    
      Page<PaymentMethod> findByNameLikeAndValidSinceGreaterThan(
        String name, Date validSince, Pageable page
      );
    
    }
    

    프레임 워크는 메소드 이름을 구문 분석합니다.

    findBy (Name like) And (보다 큰 ValidSince)

    JPA QL 쿼리를 만들고 페이징 및 정렬 (페이지 가능 페이지)을 적용하여 실행하십시오. 구현 필요 없음 :

    paymentMethodsDao.findByNameLikeAndValidSinceGreaterThan(
      "abc%",
      new Date(),
      new PageRequest(0, 20, Sort.Direction.DESC, "name"
    );
    

    결과 쿼리 :

    SELECT *  //or COUNT, framework also returns the total number of records
    FROM PaymentMethods
    WHERE name LIKE "abc%"
      AND validSince > ...
    

    페이징이 적용됩니다.

    유일한 단점은 프로젝트가 다소 새롭다는 것입니다. 그러나 충돌하기는 비교적 쉽습니다 (그러나 매우 적극적으로 개발되었습니다).

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

    3.각 개체에 대해 특정 DAO를 작성하지 마십시오. 필요한 모든 항목에 대해 작업의 90 %를 수행하는 일반 DAO를 구현할 수 있습니다. 특정 개체에 대한 특정 치료를 원하는 경우에 확장 할 수 있습니다.

    각 개체에 대해 특정 DAO를 작성하지 마십시오. 필요한 모든 항목에 대해 작업의 90 %를 수행하는 일반 DAO를 구현할 수 있습니다. 특정 개체에 대한 특정 치료를 원하는 경우에 확장 할 수 있습니다.

    내가 현재 일하고있는 프로젝트에서, 우리는 Hibernate 세션이 여러분이 설명한 것과 비슷한 메소드를 제공하는 DAO를 가지고있다. 또한 Google은 ISearch API를 사용하고 있습니다. 오픈 소스 프로젝트는 Google 코드에서 호스팅되며 Hibernate와 JPA를위한 인터페이스를 구축하는 매우 편리한 기준을 제공합니다.

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

    4.Generic DAO를 다른 Domain 특정 DAO 클래스의 영향력으로 사용할 수 있습니다. 다음과 같이 Employee Domain 클래스가 있다고 가정합니다.

    Generic DAO를 다른 Domain 특정 DAO 클래스의 영향력으로 사용할 수 있습니다. 다음과 같이 Employee Domain 클래스가 있다고 가정합니다.

      @Entity
      @Table(name="employee")
      public class Employee {
    
        @Id
        @Column(name="id")
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;
    
        @Column(name="emp_name")
        private String empName;
    
        @Column(name="emp_designation")
        private String empDesignation;
    
        @Column(name="emp_salary")
        private Float empSalary;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getEmpName() {
            return empName;
        }
    
        public void setEmpName(String empName) {
            this.empName = empName;
        }
    
        public String getEmpDesignation() {
            return empDesignation;
        }
    
        public void setEmpDesignation(String empDesignation) {
            this.empDesignation = empDesignation;
        }
    
        public Float getEmpSalary() {
            return empSalary;
        }
    
        public void setEmpSalary(Float empSalary) {
            this.empSalary = empSalary;
        }
    
    
    }
    

    필요한 제네릭 DAO는 다음과 같이 보입니다.

    일반 DAO 인터페이스 :

     public interface GenericRepositoryInterface<T> {
    
        public T save(T emp);
        public Boolean delete(T emp);
        public T edit(T emp);
        public T find(Long empId);
    }
    

    일반 DAO 구현 :

    @Repository
    public class GenericRepositoryImplementation<T> implements GenericRepositoryInterface<T> {
    
    protected EntityManager entityManager;
    private Class<T> type;
    
    public GenericRepositoryImplementation() {
        // TODO Auto-generated constructor stub
    
    }
    
    public GenericRepositoryImplementation(Class<T> type) {
        // TODO Auto-generated constructor stub
    
        this.type = type;
    }
    
    public EntityManager getEntityManager() {
        return entityManager;
    }
    
    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    @Override
    public T save(T emp) {
        // TODO Auto-generated method stub
        entityManager.persist(emp);
        entityManager.flush();
        return emp;
    }
    
    @Override
    public Boolean delete(T emp) {
        // TODO Auto-generated method stub
        try {
             entityManager.remove(emp);
        } catch (Exception ex) {
            return false;
        }
        return true;
    }
    
    @Override
    public T edit(T emp) {
        // TODO Auto-generated method stub
        try{
           return entityManager.merge(emp);
        } catch(Exception ex) {
            return null;
        }
    }
    
    @Override
    public T find(Long empId) {
        // TODO Auto-generated method stub
        return (T) entityManager.find(Employee.class, empId);
    }
    } 
    

    이 일반 DAO 클래스는 모든 도메인 별 DAO 클래스에 의해 확장되어야합니다. 도메인 특정 DAO 클래스는 일반적이지 않은 작업에 대해 다른 인터페이스를 구현할 수도 있습니다. 그리고 생성자를 사용하여 유형 정보를 보내는 것을 선호합니다.

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

    5.당신은 baseDAO 인터페이스와 baseDAO 구현 클래스를 생성 할 수 있습니다. 그리고 다른 클래스 유형으로 특정 유스 케이스가 필요한 경우 baseDAO 클래스를 상속하고 해당 클래스의 특정 요구 사항과 함께 추가 인터페이스를 구현하는 해당 클래스의 DAO를 만들 수 있습니다.

    당신은 baseDAO 인터페이스와 baseDAO 구현 클래스를 생성 할 수 있습니다. 그리고 다른 클래스 유형으로 특정 유스 케이스가 필요한 경우 baseDAO 클래스를 상속하고 해당 클래스의 특정 요구 사항과 함께 추가 인터페이스를 구현하는 해당 클래스의 DAO를 만들 수 있습니다.

    나는 DAO를 기본으로한다.

     public interface IBaseDAO<T> {
    
    /**
     * @Purpose :Save object of type T
     * @param transientInstance
     */
    public Object persist(final T transientInstance);
    
    /**
     * @Purpose :Delete object of type T
     * @param persistentInstance
     */
    public void remove(final T persistentInstance);
    
    /**
     * @Purpose :Update Object of type T
     * @param detachedInstance
     * @return
     */
    public T merge(final T detachedInstance);
    
    /**
     * @Purpose :Find object by 'id' of type T
     * @param identifier
     * @return
     */
    public T findById(final Long identifier, Class<?> persistClass);
    }
    

    BaseDAO 클래스

    public class BaseDAO<T> implements IBaseDAO<T> {
    
    @Autowired
    private SessionFactory sessionFactory;
    
    public Object persist(T entity) {
        return this.getSession().save(entity);
    }
    
    @Override
    public void remove(T persistentInstance) {
        this.getSession().delete(persistentInstance);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public T merge(T detachedInstance) {
        return (T) this.getSession().merge(detachedInstance);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public T findById(Long identifier, Class<?> persistClass) {
        return (T) this.getSession().get(persistClass, identifier);
    }
    
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
    public Session getSession() {
        return getSessionFactory().getCurrentSession();
    }
    
    }
    

    특정 인터페이스

    public interface IUserDAO extends IBaseDAO<User> {
    
       public User getUserById(long userId);
    
       public User findUserByUsername(String username);
    
    }
    

    이 수업은

    @Repository("userDAO")
    public class UserDAO extends BaseDAO<User> implements IUserDAO {
    
    public User getUserById(long userId) {
        return findById(userId, User.class);
    }
    
    @Override
        public User findUserByUsername(String username) {
            Criteria criteria = getSession().createCriteria(User.class);
            criteria.add(Restrictions.eq("username", username));
            return (User) criteria.uniqueResult();
        }
    
    }
    
  6. from https://stackoverflow.com/questions/9721383/hibernate-crud-generic-dao by cc-by-sa and MIT license