2

我有一个从 Drupal CMS 检索数据的 Java 类。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());
}
4

2 回答 2

1

通常,每个表或视图都有一个 DAO(DAO 的接口和实现它的类)。这样,如果特定表架构发生更改,您的更改将被隔离到一个 DAO 类。

您可以将内容类型概括为具有单个接口和为每种内容类型实现接口的类。这应该允许您适应通用内容类型层、特定内容类型和数据访问层的变化。

我同意它可能会变成大量代码,但是如果每个组件都与其他组件分离,那么它在更改/添加组件或处理架构更改时为您提供了灵活性。解耦和抽象在短期内可能会很痛苦,但从长远来看,往往会给整个工程团队带来回报。

我喜欢这样的问题/讨论,并且总是乐于接受建议或其他方法。

于 2012-06-11T16:53:15.697 回答
0

要创建类的新实例,您需要在类对象上使用反射装置。所以你要做的是使用一个泛型类,它的实例有该类的记录。假设你的 bean 扩展了 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);
于 2012-07-18T03:11:52.913 回答