2009-12-02 9 views
5

Quería saber qué considera la comunidad las "mejores prácticas" con respecto a la asignación de jerarquías de clase con Spring JDBC.Primavera JDBC RowMapper con Hiearchies de clase

No tenemos la capacidad de utilizar una herramienta ORM completa, sin embargo, estamos utilizando Spring JDBC para aliviar parte de la naturaleza tediosa de JDBC. Una clase que aprovechamos con mucha regularidad es BeanPropertyRowMapper por su facilidad de uso y la capacidad de tener acceso a propiedades de frijoles insensibles a los tipos de nuestro conjunto de resultados.

Tengo una jerarquía de clases que todos los mapas vuelven a una sola tabla (tomando el enfoque de tabla por jerarquía para esta pequeña jerarquía de clases). Como tal, la tabla contiene una columna classId que se puede usar para determinar qué clase se debe instanciar realmente. Ex. 1 = Gerente, 2 = Empleado, 3 = Contratista. Todos estos son "Personas" pero cada subclase de persona tiene algunos atributos que son únicos para su clase.

Mi idea inicial es crear una subclase de BeanPropertyRowMapper y probar e insertar esta lógica para decir "si la columna A = 1 luego crear una instancia de un administrador y luego hacer su enlace nominal".

¿Esto parece un enfoque razonable? ¿Hay alguna otra sugerencia que la gente pueda tener que haya funcionado para usted?

Gracias de antemano por sus respuestas,

Justin N.

Respuesta

4

No parece que haya un lugar en la subclase donde se puede añadir un gancho para cambiar la clase sin copiar por completo la aplicación de mapRow() para BeanPropertyRowMapper. Su mejor enfoque podría ser crear una clase RowMapper que delegue en el BeanPropertyRowMapper apropiado.

Por ejemplo:

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

Gracias por la respuesta. ¡Esto es lo que terminé haciendo! Es bueno obtener algo de validación. – jnt30

1

No estoy seguro de que es la 'mejor práctica' pero sugiero el siguiente enfoque (sin necesidad de utilizar las propiedades del bean -> debería funcionar más rápido).

Normalmente, usted sabe qué tipo de objeto espera recuperar. De modo que puede proporcionar el correlacionador de fila correspondiente cuando ejecuta el sql.

Declarar RowMapper genérica abstracta de encargo y crear propia fila mapeador para cada tipo de persona, es decir:

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 
} 
} 

Por otro enfoque se puede declarar método abstracto en el asignador de base para los apoyos específicos, es decir

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; 
} 
Cuestiones relacionadas