문제

커뮤니티가 스프링 JDBC와 클래스 계층을 매핑하는 것과 관련하여 "모범 사례"를 고려하는 것을 알고 싶었습니다.

우리는 완전한 신생 ORM 도구를 사용할 수있는 능력이 없지만 Spring JDBC를 사용하여 JDBC의 지루한 특성을 완화하고 있습니다. 우리가 매우 정기적으로 활용하는 한 클래스는 BeanPropertyrowmapper가 사용하기 쉽고 결과 세트에서 유형의 둔감 한 Bean 속성에 액세스 할 수있는 능력입니다.

모든 맵이 단일 테이블로 되돌아가는 클래스 계층 구조가 있습니다 (이 작은 클래스 계층에 대한 검색당 접근 방식을 취함). 따라서 테이블에는 실제로 어떤 클래스를 인스턴스화 해야하는지 결정하는 데 사용할 수있는 classid 열이 포함되어 있습니다. 전. 1 = 관리자, 2 = 직원, 3 = 계약자. 이들 모두는 "사람"이지만 사람의 각 서브 클래스에는 수업에 고유 한 몇 가지 속성이 있습니다.

나의 초기 생각은 BeanPropertyrowmapper의 서브 클래스를 만들고이 논리를 시도하고 "열 a = 1 인 경우 관리자를 인스턴스화 한 다음 겨울 바인딩을 수행한다"고 말하는 것입니다.

이것은 합리적인 접근 방식처럼 보입니까? 사람들이 당신을 위해 일한 다른 제안이 있습니까?

답변에 미리 감사드립니다.

저스틴 N.

도움이 되었습니까?

해결책

서브 클래스에 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;

            }
        }
    };

다른 팁

나는 그것이 '모범 사례'인지 확실하지 않지만 다음 접근법을 제안합니다 (Bean 특성을 사용하지 않고 -> 더 빨리 작동해야합니다).

일반적으로 검색 할 객체의 종류를 알고 있습니다. 따라서 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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top