2012-06-11 7 views
2

У меня есть класс Java, который извлекает данные из CMS Drupal. В конечном итоге в Drupal будет довольно много типов контента, которые мне нужно будет использовать в Java и кеше. Из-за того, как работает Drupal, каждый тип контента является отдельным представлением базы данных.Общий метод базы данных

У меня есть следующий метод, который вызывается сервисным слоем и возвращает определенный тип объекта. Однако мой страх - это распространение этих методов для каждого типа контента.

Может кто-нибудь предложить способ сделать его более общим? Метод базы данных показан во втором примере кода. Я не знаю, могу ли я сделать это родовым тоже, и если это того стоит. Может быть, я могу вызвать один метод в первом методе и использовать второй метод case.

public DeliverySchedule getDeliverySchedule(final String cmsKey) { //  <---- make return type (Del Schedule) generic 

    String cacheKey = TYPEDS + cmsKey; 
    DeliverySchedule cmsInstance = CMSObjectCache.getCachedCMSObject(cacheKey, DeliverySchedule.class); // Make generic 

    // Object not found in cache, go to database. 
    if (cmsInstance == null) { 
     try { 
      cmsInstance = getDeliveryScheduleFromDB(cmsKey); // <---- How can I make this generic so I can avoid DRY? 
      CMSObjectCache.putCachedCMSObject(cacheKey, new CMSObject(DeliverySchedule.class, cmsInstance)); 
      return cmsInstance; 
     } catch (EmptyResultDataAccessException e) { 
      return null; 
     } 
    } else { 
     return cmsInstance; 
    } 
} 

Метод доступа к базе данных, специфичные для типа содержимого выше:

// Called from above 
private List<DeliverySchedule> getDeliverySchedulesFromDB() { 
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 
    final String sql = "select * " 
      + "   from cmsutil.delivery_schedules as m " 
      + "   where m.effdate = (select max(mm.effdate) " 
      + "       from cmsutil.delivery_schedules as mm " 
      + "       where mm.cms_key = m.cms_key " 
      + "       and mm.effdate <= current_date)"; 


    List<DeliverySchedule> listcmsObject = jdbcTemplate.query(sql, new DeliveryScheduleMapper()); 
    return jdbcTemplate.query(sql, new DeliveryScheduleMapper()); 
} 

ответ

1

Обычно вы бы иметь DAO для каждой таблицы или представления (интерфейс для DAO и класса, который реализует его). Таким образом, если изменяется конкретная схема таблицы, ваши изменения изолированы от одного класса DAO.

Вы можете обобщить тип содержимого, чтобы иметь один интерфейс и класс, который реализует интерфейс для каждого типа контента. Это должно позволить вам адаптироваться к изменениям на уровне общего типа контента, конкретном типе контента и на уровне доступа к данным.

Я согласен, что он может превратиться во много кода, но если каждый компонент отделен от других, он дает вам гибкость при изменении/добавлении компонентов или изменении схем. Развязка и абстракция могут быть болезненными в краткосрочной перспективе, но в долгосрочной перспективе, как правило, окупаются через инженерную команду.

Мне нравятся вопросы/дискуссии, подобные этим, и я всегда открыт для предложений или других подходов.

0

Чтобы создать новые экземпляры вашего класса, вам нужно использовать механизм отражения на объекте класса. Итак, что вы делаете, вы используете общий класс, чьи экземпляры имеют запись этого класса. Скажем, ваши бобы расширяют mybean;

abstract class<T extends MyBean> Mapper implements T { 
    abstract void map(ResultSet rs); 
} 

class DAO<T extends MyBean> { 
    Class<Mapper<T>> theMapperClass; 
    DAO(Class<T> clazz) { 
     this.theMapperClass = getMapperClassFor(clazz); 
    } 

    List<T> getAList() { 
     List<T> l = new ArrayList<T>(); 
     ResultSet rs = runTheQuery(); 
     while(rs.next()) { 
      l.add(theMapperClaxx.newInstance().map(rs)); 
     } 
     return l; 
    } 
} 

Этот товар.

DAO<Foo> fooDao = new Dao<Foo>(Foo.class); 
    List<Foo> l = fooDao.getAList(); 

    List<? extends MyBean> l = someDao.getAList(); 

    static <T extends Mybean> List<T> boink(Class<T> clazz) { 
     DAO<T> tDao = (DAO<T>) daoMap.get(clazz); 
     return tDao.getAList(); 
    } 

    List<Foo> l = boink(Foo.class);