2009-12-02 2 views
5

Spring JDBC를 사용하여 클래스 계층 구조를 매핑하는 것과 관련하여 커뮤니티가 "모범 사례"라고 생각하는 것을 알고 싶었습니다.클래스 HiDBCies를 사용하는 Spring JDBC RowMapper

우리는 완전한 ORM 도구를 사용할 수 없지만, JDBC의 지루한 성격을 완화하기 위해 Spring JDBC를 사용하고 있습니다. BeanPropertyRowMapper는 우리가 매우 규칙적으로 활용하는 클래스 중 하나입니다. 사용하기 쉽고 결과 집합에서 유형을 구분하지 않는 bean 속성 액세스 권한을 가질 수 있습니다.

필자는이 모든 작은 클래스 계층 구조에 대해 table-per-hiearchy 접근법을 사용하여 모두 단일 테이블로 매핑되는 클래스 계층 구조를 사용합니다. 따라서 테이블에는 실제로 인스턴스화해야하는 클래스를 결정하는 데 사용할 수있는 classId 열이 있습니다. 전의. 1 = 관리자, 2 = 직원, 3 = 계약자. 이들 모두는 "사람들"이지만 각 개인의 하위 클래스는 자신의 클래스에 고유 한 몇 가지 속성을 가지고 있습니다.

초기 생각은 BeanPropertyRowMapper의 하위 클래스를 만들고이 논리를 삽입하여 "A 열 = 1 인 경우 관리자를 인스턴스화 한 다음 nomral 바인딩을 수행하십시오"라고 말하십시오.

이 방법이 합리적인 방법으로 보이나요? 사람들이 당신을 위해 일한 다른 제안이 있습니까? 당신의 답변에 미리

감사합니다,

저스틴 N.

답변

4

완전히의 구현을 복사하지 않고 클래스를 전환하는 후크를 추가 할 수있는 서브 클래스에있는 장소가있다처럼은 보이지 않는다 BeanPropertyRowMapper의 mapRow()입니다. 가장 좋은 방법은 적절한 BeanPropertyRowMapper에 위임하는 RowMapper 클래스를 작성하는 것입니다. 예를 들어

:

final RowMapper managerMapper = new BeanPropertyRowMapper(Manager.class); 
    final RowMapper employeeMapper = new BeanPropertyRowMapper(Employee.class); 
    final RowMapper contractorMapper = new BeanPropertyRowMapper(Contractor.class); 

    RowMapper rm = new RowMapper() 
    { 
     @Override 
     public Object mapRow(ResultSet rs, int rowNum) 
      throws SQLException 
     { 
      int employeeType = rs.getInt("type"); 
      switch (employeeType) 
      { 
       case 1: 
        return managerMapper.mapRow(rs, rowNum); 

       case 2: 
        return employeeMapper.mapRow(rs, rowNum); 

       case 3: 
        return contractorMapper.mapRow(rs, rowNum); 

       default: 
        break; 

      } 
     } 
    }; 
+0

응답 해 주셔서 감사합니다. 이것은 내가 끝내었던 것이다! 유효성을 확인하는 것이 좋습니다. – jnt30

1

나는 그것이 '모범 사례'확실하지 않다하지만 난 (-> 빠르게 작동합니다 빈 속성을 사용하지 않고) 다음과 같은 접근 방식을 제안한다.

일반적으로 어떤 종류의 개체를 가져올 것으로 예상하는지 알고 있습니다. 따라서 SQL을 실행할 때 해당 행 매핑 프로그램을 제공 할 수 있습니다. 다른 방법으로

private static abstract class PersonRowMapper<T extends Person> implements RowMapper<T> { 

@Override 
public abstract T mapRow(ResultSet rs, int rowNum) throws SQLException; 

protected void mapBase(ResultSet rs, T person) throws SQLException { 
    //base mapping here 
} 
} 


private static class EmployeeRowMapper extends PersonRowMapper<Employee> { 

@Override 
public Employee mapRow(ResultSet rs, int rowNum) throws SQLException { 
    Employee e = new Employee(); 
    mapBase(rs, e); 
    //set other specific employee props 
} 
} 

당신이

private static abstract class PersonRowMapper<T extends Person> implements RowMapper<T> { 
@Override 
public T mapRow(ResultSet rs, int rowNum) throws SQLException { 
    T instance = getInstance(); 
    //set base props here 
    fill(rs, instance); 
} 

//e.g. return new Employee() 
protected abstract T getInstance(); 
//fill specific instance props 
protected abstract void fill(ResultSet rs, T instance) throws SQLException; 
} 
즉, 특정 소품에 대한 기본 매퍼에서 추상 메소드를 선언 할 수 있습니다 : 사용자 정의 추상적 인 일반에 RowMapper 선언하고 사람의 각 유형에 대한 자신의 행 매퍼를 생성, 즉

관련 문제