- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我无法理解数据映射器设计模式。我有两个查询(一个是获取专辑,一个是获取艺术家)。我想制作一张专辑和艺术家(乐队成员)的列表。两者之间是一对多的关系。
SQL 查询
public function getArtist()
{
$adapter = $this->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('genre');
$select->where(array(
'album_id' => $album,));
$selectString = $sql->getSqlStringForSqlObject($select);
$resultSet = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);
return $resultSet;
}
public function getAlbum()
{
$adapter = $this->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('album');
$selectString = $sql->getSqlStringForSqlObject($select);
$resultSet = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);
return $resultSet;
}
当我执行类似于下面的操作时,我最终会为每个专辑运行一个单独的查询。我不想这样做。我该如何设置这样的东西 http://akrabat.com/php/objects-in-the-model-layer-part-2/ ?我可以设置每个实体代表一个查询吗(我想在我的查询中使用连接而不是为每个表创建一个实体)?
<?php foreach ($albums->getAlbum() as $album) : ?>
<tr>
<td><?php echo $this->escapeHtml($album->id);?></td>
<td><?php echo $this->escapeHtml($album->title);?></td>
<td><?php echo $this->escapeHtml($album->artist);?></td>
<td>
<?php foreach ($albums->getArtist($album->id) as $member) : ?>
使用下面提供的解决方案
ConcreteAlbumMapper.php
use Zend\Db\Adapter\AdapterInterface;
use Album\Model\AlbumMapper;
namespace Album\Model;
class ConcreteAlbumMapper implements AlbumMapper {
public function __construct(AdapterInterface $dbAdapter)
{
$this->adapter =$dbAdapter;
}
public function fetchAlbums(ArtistMapper $artistMapper) {
$adapter = $this->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('album');
$selectString = $sql->getSqlStringForSqlObject($select);
$albumRows = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);
$albums = array();
foreach ($albumRows as $albumRow) {
$albums[$albumRow['id']] = new Album($albumRow);
}
$artists = $artistMapper->fetchByAlbumIds(array_keys($albums));
//marrying album and artists
foreach ($artists as $artist) {
/**
* not crazy about the getAlbumId() part, would be better to say
* $artist->attachYourselfToAnAlbumFromThisIndexedCollection($albums);
* but going with this for simplicity
*/
$albums[$artist->getAlbumId()]->addArtist($artist);
}
return $albums;
}
}
ConcreteMemberMapper.php
<?php
namespace Album\Model;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Sql\Sql;
use Album\Model\Member;
class ConcreteMemberMapper {
public function __construct(AdapterInterface $dbAdapter)
{
$this->adapter =$dbAdapter;
}
public function getAdapter()
{
if (!$this->adapter) {
$sm = $this->getServiceLocator();
$this->adapter = $sm->get('Zend\Db\Adapter\Adapter');
}
return $this->adapter;
}
public function fetchByAlbumIds($ids) {
$adapter = $this->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('members');
$select->where(array(
'album_id' => $ids));
$selectString = $sql->getSqlStringForSqlObject($select);
$results = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);
return $results;
//return \Zend\Stdlib\ArrayUtils::iteratorToArray($results);
}
public function getAlbumId()
{
return $this->albumId;
}
}
Album.php
<?php
namespace Album\Model;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class Album //implements InputFilterAwareInterface
{
public $id;
public $title;
public $artist;
public $members = array();
public function __construct($data) {
$this->id = (!empty($data['id'])) ? $data['id'] : null;
$this->artist = (!empty($data['artist'])) ? $data['artist'] : null;
$this->title = (!empty($data['title'])) ? $data['title'] : null;
$this->members = (!empty($data['members'])) ? $data['members'] : null;
}
public function addMember(Member $member) {
$this->members[] = $member;
}
AlbumController.php
public function indexAction()
{
$dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
//$album = new Album();
$albumMapper = new ConcreteAlbumMapper($dbAdapter);
$memberMapper = new ConcreteMemberMapper($dbAdapter);
$bar=$albumMapper->fetchAlbums($memberMapper);
//$artistMapper = new
//var_dump($bar);
return new ViewModel(array(
'albums' => $bar,
));
}
非常感谢
马特
最佳答案
有很多方法可以解决这个问题,这是其中之一。假设您有一个与此类似的数据库架构:
现在您可以让 AlbumMapper 和 ArtistMapper 负责为您从数据库中获取这些对象:
interface AlbumMapper {
/**
* Fetches the albums from the db based on criteria
* @param type $albumCriteria
* @param ArtistMapper $artistMapper
*
* Note: the ArtistMapper here can be also made optional depends on your app
*/
public function fetchBySomeCriteria($albumCriteria, ArtistMapper $artistMapper);
}
interface ArtistMapper {
/**
* @param array $ids
* @return Artist[]
*/
public function fetchByAlbumIds(array $ids);
}
我已经把 AlbumMapper 需要 ArtistMapper,所以有了这个映射器,专辑总是和他们的艺术家一起返回。现在一个示例实现可以是这样的,我使用一些索引技巧将艺术家附加到专辑:
class ConcreteAlbumMapper implements AlbumMapper {
public function fetchBySomeCriteria($albumCriteria, ArtistMapper $artistMapper) {
//sql for fetching rows from album table based on album criteria
$albums = array();
foreach ($albumRows as $albumRow) {
$albums[$albumRow['id']] = new Album($albumRow);
}
$artists = $artistMapper->fetchByAlbumIds(array_keys($albums));
//marrying album and artists
foreach ($artists as $artist) {
/**
* not crazy about the getAlbumId() part, would be better to say
* $artist->attachYourselfToAnAlbumFromThisIndexedCollection($albums);
* but going with this for simplicity
*/
$albums[$artist->getAlbumId()]->addArtist($artist);
}
return $albums;
}
}
在这种情况下,您的相册将是:
class Album {
private $id;
private $title;
private $artists = array();
public function __construct($data) {
//initialize fields
}
public function addArtist(Artist $artist) {
$this->artists[] = $artist;
}
}
在所有这一切结束时,您应该有一个用艺术家初始化的 Album 对象集合。
关于php - 如何在 sql 查询中使用数据映射器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27277173/
我有三张 table 。表 A 有选项名称(即颜色、尺寸)。表 B 有选项值名称(即蓝色、红色、黑色等)。表C通过将选项名称id和选项名称值id放在一起来建立关系。 我的查询需要显示值和选项的名称,而
在mysql中,如何计算一行中的非空单元格?我只想计算某些列之间的单元格,比如第 3-10 列之间的单元格。不是所有的列...同样,仅在该行中。 最佳答案 如果你想这样做,只能在 sql 中使用名称而
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
我正在为版本7.6进行Elasticsearch查询 我的查询是这样的: { "query": { "bool": { "should": [ {
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
是否可以编写一个查询来检查任一子查询(而不是一个子查询)是否正确? SELECT * FROM employees e WHERE NOT EXISTS (
我找到了很多关于我的问题的答案,但问题没有解决 我有表格,有数据,例如: Data 1 Data 2 Data 3
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
我从 EditText 中获取了 String 值。以及提交查询的按钮。 String sql=editQuery.getText().toString();// SELECT * FROM empl
我有一个或多或少有效的查询(关于结果),但处理大约需要 45 秒。这对于在 GUI 中呈现数据来说肯定太长了。 所以我的需求是找到一个更快/更高效的查询(几毫秒左右会很好)我的数据表大约有 3000
这是我第一次使用 Stack Overflow,所以我希望我以正确的方式提出这个问题。 我有 2 个 SQL 查询,我正在尝试比较和识别缺失值,尽管我无法将 NULL 字段添加到第二个查询中以识别缺失
什么是动态 SQL 查询?何时需要使用动态 SQL 查询?我使用的是 SQL Server 2005。 最佳答案 这里有几篇文章: Introduction to Dynamic SQL Dynami
include "mysql.php"; $query= "SELECT ID,name,displayname,established,summary,searchlink,im
我有一个查询要“转换”为 mysql。这是查询: select top 5 * from (select id, firstName, lastName, sum(fileSize) as To
通过我的研究,我发现至少从 EF 4.1 开始,EF 查询上的 .ToString() 方法将返回要运行的 SQL。事实上,这对我来说非常有用,使用 Entity Framework 5 和 6。 但
我在构造查询来执行以下操作时遇到问题: 按activity_type_id过滤联系人,仅显示最近事件具有所需activity_type_id或为NULL(无事件)的联系人 表格结构如下: 一个联系人可
如何让我输入数据库的信息在输入数据 5 分钟后自行更新? 假设我有一张 table : +--+--+-----+ |id|ip|count| +--+--+-----+ |
我正在尝试搜索正好是 4 位数字的 ID,我知道我需要使用 LENGTH() 字符串函数,但找不到如何使用它的示例。我正在尝试以下(和其他变体)但它们不起作用。 SELECT max(car_id)
我有一个在 mysql 上运行良好的 sql 查询(查询 + 连接): select sum(pa.price) from user u , purchase pu , pack pa where (
我是一名优秀的程序员,十分优秀!