2009-12-02 10 views
5

Toplumun JDBC ile sınıf hiyerarşilerinin eşleştirilmesiyle ilgili olarak “en iyi uygulamaları” nı nasıl değerlendirdiğini öğrenmek istedim.Spring Sınıf Aramaları ile JDBC RowMapper

Tam teşekküllü bir ORM aracı kullanma yetkimiz yok, ancak JDBC'nin sıkıcı doğasını hafifletmek için Spring JDBC'yi kullanıyoruz. Çok düzenli olarak kullandığımız bir sınıf, kullanım kolaylığı ve sonuç kümemizden türden duyarsız fasulye mülküne erişme yeteneği için BeanPropertyRowMapper'dır.

Tüm sınıfların tek bir tabloya dönüştüğü bir sınıf hiyerarşisine sahibim (bu küçük sınıf hiyerarşisinde tablo başına yaklaşım yaklaşımını alarak). Bu nedenle, tablo hangi sınıfın gerçeklenmesi gerektiğini belirlemek için kullanılabilecek bir classId sütunu içerir. Ör. 1 = Yönetici, 2 = Çalışan, 3 = Yüklenici. Bunların hepsi "İnsan" dır, fakat her bir alt sınıfın kendi sınıflarına özgü bir kaç özelliği vardır.

İlk düşüncem BeanPropertyRowMapper'ın bir alt sınıfını oluşturmak ve "mantık A = 1 ise, sonra bir Yönetici başlatıp sonra da sizin bağlayıcılığını yapmak" ifadesini almak için bu mantığı enjekte etmektir.

Bu mantıklı bir yaklaşım gibi görünüyor mu? İnsanların sizin için çalışmış olabilecek başka önerileri var mı? cevaplar için şimdiden

sayesinde

Justin N.

cevap

4

tamamen uygulanmasını kopyalamadan sınıfını geçmek için bir kanca ekleyebilirsiniz alt sınıfta yer kalmamış gibi görünmüyor BeanPropertyRowMapper için mapRow(). En iyi yaklaşımınız, uygun BeanPropertyRowMapper'a delege veren bir RowMapper sınıfı oluşturmak olabilir. Örneğin

:

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

Yanıt için teşekkürler. Yaptığım şey bu! Doğrulama yapmak güzel. – jnt30

1

Ben 'en iyi uygulama' olduğundan emin değilim ama (-> hızlı çalışması gerekir fasulye özelliklerini kullanmadan) aşağıdaki yaklaşımı göstermektedir.

Genellikle, nasıl bir nesneyi almayı beklediğinizi bilirsiniz. Böylece sql çalıştırırken ilgili satır eşleştiricisi sağlayabilirsiniz. Diğer bir yaklaşım olarak

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

Eğer

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; 
} 
yani belirli sahne için taban eşleştiricisindeki soyut yöntem bildirebilirsiniz: özel soyut jenerik RowMapper bildirmek ve kişinin her tip için kendi satır mapper oluşturmak, yani