Question

Je voulais savoir ce que la communauté considère les "meilleures pratiques" en ce qui concerne la cartographie des hiérarchies de classe avec le printemps JDBC.

Nous n'avons pas la possibilité d'utiliser un outil ORM à part entière, mais nous utilisons le Spring JDBC pour atténuer une partie de la nature fastidieuse de JDBC. Une classe que nous expliquons très régulièrement est le beanpropertyrowmapper pour sa facilité d'utilisation et la possibilité d'avoir un accès de propriété de bean insensible à type à partir de notre ensemble de résultats.

J'ai une hiérarchie de classe qui revient toutes à une seule table (en prenant l'approche de table par hiearchy pour cette hiérarchie de petites classes). En tant que tel, le tableau contient une colonne classique qui peut être utilisée pour déterminer quelle classe doit réellement être instanciée. Ex. 1 = gestionnaire, 2 = employé, 3 = entrepreneur. Tous ce sont des «gens» mais chaque sous-classe de personne a quelques attributs qui sont uniques à leur classe.

Ma pensée initiale consiste à créer une sous-classe de beanpropertyrowmapper et d'essayer d'injecter cette logique pour dire "Si la colonne A = 1 puis instancier un gestionnaire, puis faites votre liaison nomrale".

Cela semble-t-il une approche raisonnable? Y a-t-il d'autres suggestions que les gens peuvent avoir qui ont fonctionné pour vous?

Merci d'avance pour vos réponses,

Justin N.

Était-ce utile?

La solution

Il ne semble pas qu'il y ait une place dans la sous-classe où vous pouvez ajouter un crochet pour changer la classe sans copier complètement l'implémentation de MapRow () pour beanpropertyrowmapper. Votre meilleure approche pourrait être de créer une classe RowMapper qui délégue au beanpropertyrowmapper approprié.

Par exemple:

    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;

            }
        }
    };

Autres conseils

Je ne suis pas sûr que ce soit la «meilleure pratique», mais je suggère l'approche suivante (sans utiliser les propriétés des haricots -> devrait fonctionner plus rapidement).

Habituellement, vous savez quel type d'objet vous vous attendez à récupérer. Ainsi, vous pouvez fournir un mappeur de ligne correspondant lors de l'exécution du SQL.

Déclarez la RowMapper générique abstraite personnalisée et créez un mappeur de ligne pour chaque type de personne, c'est-à-dire:

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

Par une autre approche, vous pouvez déclarer la méthode abstraite dans le mappeur de base pour des accessoires spécifiques, c'est-à-dire

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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top