복붙노트

[SPRING] 봄 일반 Dao 클래스 이름

SPRING

봄 일반 Dao 클래스 이름

Spring / Hibernate 프로젝트를 위해 커스텀 제네릭 서비스 DAO를 구성했습니다 - 내 컨트롤러에서 쉽게 재사용 할 수있는 아이디어입니다.

기본적으로 다음과 같습니다.

public class DefaultService<T> {

private Class<T> e;

public String className(Class<T> e) {
    String clip = e.getName();
    clip = clip.substring(clip.lastIndexOf('.') + 1, clip.length());
    return clip;
}
public List<T> getAll(Integer status) {
    Session session = sessionFactory.getCurrentSession();
    Query query = session.createQuery("FROM " + className(e) + " WHERE status = " + status);
    return query.list();
}
...

다음에 의해 참조됩니다.

@Autowired
public DefaultService<Address> addressService;
addressService.get(1);

그러나 String clip = e.getName () 행은 Null 포인터 예외를 발생시킵니다. 클래스를 애트리뷰트 섹션으로 옮기면이 작업을 수행 할 수 있습니다 (예 : addressService.get (Address.class, 1)) 그러나 여러 다른 클래스가 호출 될 때 특히 다소 어수선해합니다.

내 모든 함수에 반복적으로 추가하지 않고 클래스가 값을 올바르게 생성하도록하는 방법이 있습니까?

미리 감사드립니다.

해결법

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

    1.비슷한 것을 했었습니다. 생성자 인자가되기 위해서 제네릭 클래스가 필요합니다. 내 것은 최대 절전 엔티티를 사용하지만, 테이블 이름의 문자열을 전달할 수 있습니다.

    비슷한 것을 했었습니다. 생성자 인자가되기 위해서 제네릭 클래스가 필요합니다. 내 것은 최대 절전 엔티티를 사용하지만, 테이블 이름의 문자열을 전달할 수 있습니다.

    public class DomainRepository<T> {
    
        @Resource(name = "sessionFactory")
        protected SessionFactory sessionFactory;
    
     public DomainRepository(Class genericType) {
            this.genericType = genericType;
        }
    
     @Transactional(readOnly = true)
        public T get(final long id) {
            return (T) sessionFactory.getCurrentSession().get(genericType, id);
        }
    

    그런 다음 하위 클래스 (필요한 경우)를 사용자 정의하거나 간단히 봄 설정에서 다음과 같이 설정할 수 있습니다.

    <bean id="tagRepository" class="com.yourcompnay.data.DomainRepository">
            <constructor-arg value="com.yourcompnay.domain.Tag"/>
    </bean>
    

    따라서 코드에서 tagRepository를 참조 할 수 있습니다 (위에 게시 한 것보다 아래에 다른 코드는 필요하지 않습니다).

    @Resource(name = "tagRepository")
    private DomainRepository<Tag> tagRepository;
    

    또한 서비스가 아닌 리포지토리라고 부르겠습니다. 서비스는 다양한 유형과 상호 작용 (하나뿐 아니라)을 처리합니다. 특히 SQL 문자열을 사용하는 예제는 다음과 같습니다.

    public final String tableName;
    public DomainRepository(String tableName) {
          this.tableName = tableName;
    }
    public List<T> getAll(Integer status) {
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("FROM " + tableName + " WHERE status = " + status);
        return query.list();
    }
    

    너의 콩을 이렇게 정의해라.

    <bean id="addressRepository" class="com.yourcompnay.data.DomainRepository">
      <constructor-arg value="address"/>
    </bean>
    

    그리고 필요한 경우 직접 하위 클래스를 만들 수도 있습니다.

    public class PersonRepository extends DomainRepository<Person> {
        public PersonRepository(){
            super("person"); //assumes table name is person
        }
    
  2. ==============================

    2.이 필드에 값을 설정하지 않았으므로 NPE를 얻었습니다. 따라서 다음 두 가지 방법으로이 문제를 해결할 수 있습니다.

    이 필드에 값을 설정하지 않았으므로 NPE를 얻었습니다. 따라서 다음 두 가지 방법으로이 문제를 해결할 수 있습니다.

    보호 된 클래스 getEntityClass () {         GenericTypeResolver.resolveTypeArguments (getClass (), DefaultService.class)를 반환합니다. [0]; }

    또는 여기에서 몇 가지 해결 방법

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

    3.주소 서비스에 대한 특정 클래스를 정의하는 것이 좋습니다

    주소 서비스에 대한 특정 클래스를 정의하는 것이 좋습니다

    public class AddressService extends DefaultService<Address>{
      public String getClassName(){
       return "Address";
      }
    }
    

    어디에

    public String getClassName();
    

    DefaultService에서 선언 된 추상 메소드이며, 데이터 액세스 로직에서 className () 메소드와 같이 사용됩니다.

    이 방법을 사용하면 특정 데이터 액세스 로직 (예 : getUsersByAddress)을 추가 할 수 있습니다.

  4. from https://stackoverflow.com/questions/15002836/spring-generic-dao-class-name by cc-by-sa and MIT license