Frage

Ich wollte wissen, was die Community als "Best Practices" in Bezug auf die Kartierung von Klassenhierarchien mit Spring JDBC betrachtet.

Wir haben nicht die Möglichkeit, ein vollwertiges Orm -Tool zu verwenden, aber wir verwenden das Spring JDBC, um einen Teil der mühsamen Natur von JDBC zu lindern. Eine Klasse, die wir sehr regelmäßig nutzen, ist der BeanPropertyRowmapper für die Benutzerfreundlichkeit und die Fähigkeit, einen unempfindlichen Bean -Immobilienzugriff aus unserem Ergebnissatz zu haben.

Ich habe eine Klassenhierarchie, die alle auf eine einzelne Tabelle zurückbleiben (die Tabelle-Per-Hiearchy-Ansatz für diese kleine Klassenhierarchie). In der Tabelle enthält die Tabelle eine Klassikspalte, mit der bestimmen kann, welche Klasse tatsächlich instanziiert werden soll. Ex. 1 = Manager, 2 = Mitarbeiter, 3 = Auftragnehmer. All dies sind "Menschen", aber jede Unterklasse von Person hat einige Attribute, die für ihre Klasse einzigartig sind.

Mein erster Gedanke ist, eine Unterklasse von BeanPropertyRowmapper zu erstellen und diese Logik zu injizieren, um zu sagen: "Wenn Spalte A = 1 dann einen Manager instanziiert und dann Ihre Nominalbindung durchführen".

Scheint das ein vernünftiger Ansatz? Gibt es andere Vorschläge, die Menschen für Sie möglicherweise gearbeitet haben?

Vielen Dank im Voraus für Ihre Antworten,

Justin N.

War es hilfreich?

Lösung

Es sieht nicht so aus, als ob es einen Ort in der Unterklasse gibt, an dem Sie einen Haken hinzufügen können, um die Klasse zu wechseln, ohne die Implementierung von Maprow () für BeanPropertyRowmapper vollständig zu kopieren. Ihr bester Ansatz könnte darin bestehen, eine RowMapper -Klasse zu erstellen, die den entsprechenden BeanpropertyRowMapper delegiert.

Zum Beispiel:

    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;

            }
        }
    };

Andere Tipps

Ich bin mir nicht sicher, ob es die "Best Practice" ist, aber ich schlage den folgenden Ansatz vor (ohne Beaneigenschaften -> sollte schneller funktionieren).

Normalerweise wissen Sie, welche Art von Objekt Sie erwarten, abzurufen. So können Sie bei der Ausführung des SQL entsprechenden Zeilen -Mapper angeben.

Deklarieren Sie benutzerdefinierte abstrakte generische RowMapper und erstellen Sie für jeden Personenart einen eigenen Zeilen -Mapper, dh:

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

Nach einem anderen Ansatz können Sie die abstrakte Methode in Base Mapper für bestimmte Requisiten deklarieren, dh

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top