我正在用PHP编写一个系统,它必须写入三个持久层:
原因是遗留系统无法更改.
我想使用DataMapper模式,我正在尝试建立实现我想要的最佳方式.我有一个如下界面:
<?php
$service = $factory->getService()->create($entity);
?>
Run Code Online (Sandbox Code Playgroud)
为简洁起见,下面是一些人为的和减少的代码:
<?php
class Post extends AbstractService
{
protected $_mapper;
public function create(Entity $post)
{
return $this->_mapper->create($post);
}
}
class AbstractMapper
{
protected $_persistence;
public function create(Entity $entity)
{
$data = $this->_prepareForPersistence($entity);
return $this->_persistence->create($data);
}
}
?>
Run Code Online (Sandbox Code Playgroud)
我的问题是因为有三个持久层,因此每个都可能需要三个映射器.我想要一个干净的设计模式灵感的界面,使这项工作.
我认为它有三个选项:
这些解决方案中的每个解决方案都让我觉得错误,并且会感谢任何可能适合这种情况的反馈/认可的设计模式.
我正在用PHP构建应用程序,我正在使用数据映射器模式进行数据库访问.我正在考虑使用Observer模式让我的所有映射器观察它们创建的实体,这样它们就可以自动将任何更改保存回数据库而无需手动解析它们.
我只是想知道这是不是一个好主意,或者这是不好的做法等等?
我通常使用一些在层次结构中链接在一起的对象,并且目前必须手动将每个对象解析为它的映射器,这是相当繁琐的,所以只是尝试提出一个更好的解决方案.
谢谢,杰克
我是DataMapper ORM的初学者,所以我对复杂的查询有疑问.
首先,这是简化的数据对象:
class User
property :id, Serial
property :login, String
has n, :actions
end
class Item
property :id, Serial
property :title
has n, :actions
has n, :users, :through => :actions
end
class Action
property :user_id, Integer
property :item_id, Integer
belongs_to :item
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)
这就是db中的数据的样子:
+ ------- + + ------- + + ------- +
| Users | | Items | | Actions |
+ ------- + + ------- + + ------- +
| 1 | u1 | | 3 …Run Code Online (Sandbox Code Playgroud) 我正在编写一个应用程序,它要求主/从交换机在应用层内部发生.就像现在一样,我在创建映射器时实例化一个Zend_Db_Table对象,然后将setDefaultAdapter设置为从属.
现在在base mapper classe里面,我有以下方法:
public function useWriteAdapter()
{
if(Zend_Db_Table_Abstract::getDefaultAdapter() != $this->_writeDb)
{
Zend_Db_Table_Abstract::setDefaultAdapter($this->_writeDb);
$this->_tableGateway = new Zend_Db_Table($this->_tableName);
}
}
Run Code Online (Sandbox Code Playgroud)
我需要对此进行健全性检查.我不认为开销太大,我只是怀疑必须有更好的方法.
假设我们有"用户"和"酒店"模型类.我使用User_Mapper和Hotel_Mapper来加载/保存/删除等.然后我想让用户能够标记他们的"最喜欢的"酒店.在数据库中,我有我的user_favourite_hotels表,这是一个简单的链接表,以及一个用于订阅酒店更新的字段.
列出用户最喜欢的酒店时,从API的角度来看,您希望如何运作?我的一部分认为这应该是Hotel_Mapper上的"findFavouritesByUserId"方法,但不是说它"感觉"正确 - 但是同事建议"收藏夹"由用户拥有,因此应该在User_Mapper上.
也许我应该有一个User_Hotel_Favourites_Mapper?我想将"收藏夹"数据合并到User对象中,以便在User对象被保存和加载时.我不确定将它拆分为自己的对象和映射器是否更好.
对于如何最好地为上述和任何优点/缺点/经验设置API,我将不胜感激.
非常感谢,
詹姆士.
我在Zend Framework中唱出数据映射器模式.到目前为止,这种方法效果很好,但现在我需要你的帮助/意见.那么让我们从代码开始:
我们得到了一个有几个人的桌子:
CREATE TABLE `persons` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int(3) NOT NULL,
`haircolor` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id``),
);
Run Code Online (Sandbox Code Playgroud)
现在我尝试选择所有棕色头发的人.我在ServiceLayer中使用以下方法
public function getPeopleByHaircolor($hair) {
return $this->getMapper()->fetch('haircolor = ?', $hair);
}
Run Code Online (Sandbox Code Playgroud)
Mapper中的方法如下所示:
public function fetch($condition, $value) {
$resultSet = $this->getTable()->fetchAll($this->getTable()->select()->where($cond, $value));
$entries = array();
foreach($resultSet as $row) {
$entry = new Default_Model_Person();
$entry->id = $row->id;
$entry->name = $row->name;
[...]
}
return $entries;
}
Run Code Online (Sandbox Code Playgroud)
我想我用这种方法遵循Data Mapper模式......
现在问题:
我想选择棕色头发且年龄小于20岁的人.那我该怎么办呢?我的尝试:
public function getTeens($hair) {
$rows …Run Code Online (Sandbox Code Playgroud) 我正在编写一个简单的应用程序,它接受用户的标准输入.至于电子邮件条目,我让它验证它是否是标准的电子邮件格式,然后让它在要保存新实例时列出这样的问题:
u = User.new
u.email = params[:email]
u.save
if u.save
redirect '/'
else
u.errors.each do |e|
puts e
end
end
Run Code Online (Sandbox Code Playgroud)
我知道如果它是正确的,它应该返回主页.如果它是错的我也希望它返回主页,但我希望它返回一个错误值(所以我可以弹出窗口或只是屏幕上的东西让用户知道电子邮件的格式是错误的).最好的方法是什么?
我们在Sinatra应用程序中使用Datamapper,并且希望使用不区分大小写,就像Sqlite(开发中的本地)和Postgresql(生产中的Heroku)一样.
我们有这样的陈述
TreeItem.all(:name.like =>"%#{term}%",:unique => true,:limit => 20)
Run Code Online (Sandbox Code Playgroud)
如果term是"BERL",我们从Sqlite和Postgresql后端获得建议"BERLIN".但是,如果term是"Berl",我们只从Sqlite而不是Postgresql获得结果.
我想这与dm-postgres-adapter和dm-sqlite-adapter LIKE在结果SQL查询中输出a这一事实有关.由于Postgresql具有区分大小写,因此LIKE我们得到了这个(对于我们不需要的)行为.
有没有办法像Datamapper一样获得不区分大小写,而不需要使用原始SQL查询到适配器或修补适配器ILIKE而不是LIKE?
我当然可以在两者之间使用某些东西,例如:
TreeItem.all(:conditions => ["name LIKE ?","%#{term}%"],:unique => true,:limit => 20)
Run Code Online (Sandbox Code Playgroud)
但是我们将在我们自己的代码中使用Postgresql,而不仅仅是作为适配器的配置.
我使用symfony 2.3和php doctrine 2.
该计划有以下型号:
AND MAIN CLASS BadOrderList - 错误订单列表,此类代码:
private $factory;
private $repository;
private $manager;
public function __construct(
BadOrderEntryFactory $f,
BadOrderEntryRepository $r,
BadOrderEntryManager $m
) {
$this->factory = $f;
$this->repository = $r;
$this->manager = $m;
}
public function has(Order $order)
{
return $this->repository->existsByOrder($order);
}
public function add(Order $order)
{
if (! $this->has($order)) {
$entry = $this->factory->create($order);
$this->manager->save($entry);
}
}
public function remove(Order $order)
{
$entry = $this->repository->findOneByOrder($order);
if ($entry …Run Code Online (Sandbox Code Playgroud)首先介绍一些背景:我有一些相当简单的数据结构,它们作为json文件保存在磁盘上.这些json文件在不同语言和不同环境的应用程序(如Web前端和数据操作工具)之间共享.
对于我想要创建Python"POPO"(普通旧Python对象)的每个文件,以及每个项目的相应数据映射器类应该实现一些简单的CRUD行为(例如,save将序列化类并存储为json文件磁盘).
我认为一个简单的映射器(只知道基本类型)将起作用.但是,我担心安全问题.一些json文件将由Web前端生成,因此如果用户向我提供了一些糟糕的json,则可能存在安全风险.
最后,这里是简单的映射代码(在如何将JSON数据转换为Python对象中找到):
class User(object):
def __init__(self, name, username):
self.name = name
self.username = username
import json
j = json.loads(your_json)
u = User(**j)
Run Code Online (Sandbox Code Playgroud)
您看到了哪些可能的安全问题?
注意:我是Python的新手.
编辑:全部感谢您的评论.我发现我有一个json,我有2个数组,每个都有一个地图.不幸的是,当我得到更多这些时,这开始变得很麻烦.
我正在将问题扩展到将json输入映射到recordtype.原始代码来自:https://stackoverflow.com/a/15882054/1708349.因为我需要可变对象,所以我将其更改为使用namedlist而不是namedtuple:
import json
from namedlist import namedlist
data = '{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}'
# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(data, object_hook=lambda d: namedlist('X', d.keys())(*d.values()))
print x.name, x.hometown.name, x.hometown.id
Run Code Online (Sandbox Code Playgroud)
它还安全吗?
datamapper ×10
php ×5
oop ×2
ruby ×2
architecture ×1
doctrine-orm ×1
json ×1
master-slave ×1
orm ×1
postgresql ×1
python ×1
sinatra ×1
symfony ×1