当前位置: 首页 > 面试题库 >

谁应该处理复杂查询,数据映射器或服务层中的条件?

皇甫浩壤
2023-03-14
问题内容

这个问题在消除我的困惑方面做得很好,但是我很难找到关于服务层的确切限制应有的可靠信息来源。

对于此示例,假设我们正在处理书籍,并且我们希望按作者获取书籍。本BookDataMapper可以有一个通用的get()接受条件(S),如书的唯一标识符,作者姓名等这个实现是相当微不足道的(逻辑)方法,但如果我们希望有需要更复杂的查询多个条件是什么?

假设我们要让某个作者在特定出版商下撰写的所有书籍。我们可以扩展该BookDataMapper->get()方法以解析多个条件,或者可以编写一个新方法,例如BookDataMapper->getByAuthorAndPublisher()

是让服务层直接调用这些[更特定的]方法,还是在BookDataMapper->get()通过多个条件调用更通用的方法之前对条件进行解析?在后一种情况下,服务层将执行更多的逻辑“繁重工作”,从而使数据映射器相当简单。前一种选择将服务层几乎全部缩减为一个中间人,而在诸如的方法中将条件逻辑留给了数据映射器BookDataMapper->getByAuthorAndPublisher()

让服务层解析条件的显而易见的担忧是,某些域逻辑从数据映射器中泄漏出来。但是,如果服务层要处理条件,则逻辑不会使它超出模型层;$book_service->getByAuthorAndPublisher()无论如何,控制器都会调用。


问题答案:

数据映射器 模式只告诉你,什么是应该做的,它不应该如何实现。
因此,本主题中的所有答案都应视为主观答案,因为它们反映了每个作者的个人喜好。

通常 尝试使mapper的界面尽可能简单:

  • fetch(),检索域对象或集合中的数据,
  • save(),保存(更新现有内容或插入新内容)域对象或集合
  • remove(),从存储介质中删除域对象或集合

我将条件保留在域对象本身中:

$user = new User;
$user->setName( 'Jedediah' );

$mapper = new UserMapper;
$mapper->fetch( $user );

if ( $user->getFlags() > 5  )
{
    $user->setStatus( User::STATUS_LOCKED );
}

$mapper->save( $user );

这样,您可以具有多种检索条件,同时保持界面清洁。

不利的一面是,您需要一个公共方法来从域对象中检索信息以拥有这种fetch()方法,但是无论如何您都将需要它来执行save()

没有真正的方法来实现映射器和域对象交互的 “告诉不要问” 的经验法则。

至于 “如何确保您确实需要保存域对象?”
,您可能会想到,此处已进行了介绍,其中包含大量的代码示例和注释中的一些有用内容。

更新资料

如果您希望处理一组对象,那么应该处理不同的结构,而不是简单的 Domain Objects

$category = new Category;
$category->setTitle( 'privacy' );

$list = new ArticleCollection;

$list->setCondition( $category );
$list->setDateRange( mktime( 0, 0, 0, 12, 9, 2001) );
// it would make sense, if unset second value for range of dates 
// would default to NOW() in mapper

$mapper = new ArticleCollectionMapper;
$mapper->fetch( $list );

foreach ( $list as $article )
{
    $article->setFlag( Article::STATUS_REMOVED );
}

$mapper->store( $list );

在这种情况下,集合是光荣的数组,具有接受不同参数的能力,然后将这些参数用作映射器的条件。当映射器尝试存储集合时,它还应允许映射器从该集合中获取已 更改的
域对象的列表。

在这种情况下,映射器应该能够构建(或使用预设的)条件下的所有 可能
条件的查询(作为开发人员,您将了解所有这些条件,因此您无需使其在无限条件下工作)为该集合包含的所有未保存域对象更新或创建新条目。

注意: 在某些方面,您可以说映射器与构建器/工厂模式有关。目标是不同的,但是解决问题的方法非常相似。



 类似资料:
  • 在Spring的上个版本中,用户需要在web应用的上下文中定义一个或多个的HandlerMappingbean,用以将进入容器的web请求映射到合适的处理器方法上。允许在控制器上添加注解后,通常你就不必这么做了,因为RequestMappingHandlerMapping类会自动查找所有注解了@RequestMapping的@Controller控制器bean。同时也请知道,所有继承自Abstra

  • 17.5. 处理器映射 通过处理器映射,可以把进来的portlet请求对应到合适的处理器上。已经有一些 现成的处理器映射可以使用,比如PortletModeHandlerMapping。 但还是让我们先看一下HandlerMapping的一般概念。 注意,我们这里有意使用“处理器”来代替“控制器”。 DispatcherPortlet是设计用来和多种方式一起处理请求的, 而不仅仅是和Spring

  • 我们最初有一个teamcity服务器实例和一个youtrack实例。我们工作的项目是一个基于插件的项目,因此随着时间的推移,我们使用映射特性在CI构建和youtrack之间进行了相当多的映射。 现在的问题是,我们已经将该特定项目及其100多个插件移到了一个新的teamcity构建服务器上,并且现在面临的前景是必须手动重新添加已经存在的映射,因为所有其他项目仍然通过现有的构建服务器进行管理 Team

  • 问题内容: 我想用cakephp进行这样的查询: 这是我的$ conditions代码: 我正在使用Debugger :: dump()方法显示结果,并且结果仅使用最后一个“ OR”条件,而不是同时使用“ OR”条件: 我的问题是,如何进行查询以同时使用“ OR”条件? 请尽快回复..在此先感谢:) 问题答案: 请尝试以下方法: 将是 任何阵列没有指定,或者是。无需手动指定。

  • 我使用Spring引导和Spring数据JPA。它工作得很好但是!我需要使用复杂的本地查询从Oracle数据库(源数据从SAP ERP)。 假设查询包含5个joned表(一个键或组合键)。我可以使用很多参数。 解决方案: 1)由于耗时,使用JPA为该查询编写新查询是不真实的。创建表之间的所有键关系似乎很复杂。 2)为了运行这些查询,我使用JDBC。这很容易,因为我准备了本机查询。但我深信这种做法是

  • 问题内容: 我对数据库还很陌生,所以如果这是一个愚蠢的问题,请原谅我。 在现代数据库中,如果我使用索引来访问行,则我相信这将是O(1)复杂性。但是,如果我查询选择另一列,它是O(1)还是O(n)?数据库是否必须遍历所有行,还是为每列建立一个排序列表? 问题答案: 实际上,我认为基于索引的访问将是O(log(n)),因为您仍将通过类似B-Tree的组织进行搜索以获取记录。