为通用数据库模型设计数据访问层

时间:2014-06-10 15:06:48

标签: java spring architecture dao

我是一名相当缺乏经验的初级开发人员,为德国的初创公司工作。我目前正在重构一个高度分散的代码库,试图优化设计......

问题

实现数据访问层时,我们可以选择遵循DAO模式的原则。只要我们处理的实体相当具体(例如,用户,发票,账户等),这种方法就可以正常运行。 但是当我们有一个更通用的数据库模型时,我们可能经常感到需要查询作为几个表的组合的特定结果集。通常,我们应该将查询方法分配给哪个数据访问对象并不明显。

示例

采用OSM(openstreetmap.org)数据库:实际上,只有节点,方式和关系构成了许多不同对象(例如街道,建筑物,交通标志等)的表示。当查询舒适性时,它可以由单个节点(单个点,例如纪念馆),方式(路径,可以说是博物馆的轮廓)或方式集合(例如大学校园的建筑物)来表示。

除此之外,我可能只对可用信息的一小部分感兴趣,并且获取完整实体可能是开销。或者我可以在查询中使用特定于数据库的函数,这会导致结果从底层实体模型中进一步抽象。

我在代码中给你一个例子(在java中,使用spring-frameworks存储库接口):

public class IWayRepository extends Repository<Way, Long> {
    ...
    @Query(value = "select distinct ways.tags->'addr:interpolation' as type,"
      + "trim(both '{}' from text(ways.nodes)) as nodes from nodes, way_nodes, ways "
      + "where nodes.tags->'addr:street'=? and way_nodes.node_id=nodes.id "
      + "and ways.id=way_nodes.way_id "
      + "and st_intersects(st_geometryfromtext(?,4326),nodes.geom)"
      + "and exist(ways.tags,'addr:interpolation')=true", nativeQuery = true)
    List<Map<String, Object>> findAdressInterpolationInfoForStreetInBbox(String street,
      String bbox);
    ...
}

代码查询多个表,使用数据库层上的函数更改数据,并返回几乎不适合给定实体域的数据提取。

为了改进设计,我现在想到两种选择。

  • 组成一个更具体的数据访问类:AddressRepository,我访问裸结果集。但我真的不喜欢这个主意。
  • 组成一个更通用的服务类:例如LocalizationService。

问题

是否有任何既定的做法来处理这种情况?如何设计对通用数据库模型的数据访问。是否应该遵循模式?

提前谢谢!

1 个答案:

答案 0 :(得分:3)

您可以从经理(即mediator)设计模式中提取您的解决方案。您可以拥有多个DAO类和一个管理器来控制它:http://tutorials.jenkov.com/java-persistence/dao-manager.html。管理员提供对将要使用的DAO的访问权限,在您指出的更具体或通用的DAO之间。