首页 > php教程 > 正文

PHP领域模型和数据映射器详解

原创 2018-02-12 10:44:19 0 184
本文主要和大家分享PHP领域模型和数据映射器详解,简单介绍一下我的看法,从数据库操作的角度看领域模型主要是操作数据表中的单条记录的而数据映射器是操作整个数据表的数据的。

按原文的解释数据映射器是一个负责将数据库数据映射到对象的类,而领域模型象征着真实世界里项目中的各个参与者,它在数据中通常表现为一条记录。

废话不多说,代码和注解如下:

与领域模型相关的三个数据表结构分别为venue(场所)、space(空间)、event(事件)。


create table 'venue' (
   'id' int(11) not null auto_increment,
   'name' text,
   primary key ('id')
)
create table 'space' (
   'id' int(11) not null auto_increment,
   'venue' int(11) default null,
   'name' text,
   primary key ('id')
)
create table 'event' (
   'id' int(11) not null auto_increment,
   'space' int(11) default null,
   'start' mediumtext,
   'duration' int(11) default null,
   'name' text,
   primary key ('id')
)


//领域模型(这里只建了一个Venue类用于理解)
namespace woo\domain;

abstract class DomainObject{      //抽象基类
  
  private $id;
  
  function __construct ($id=null){
    $this->id = $id;
  }
  
  function getId(){
    return $this->id;
  }
  
  //原书没有具体实现,应该是用于获取对象的从属对象的,比如venue(场所)相关的space(空间)对象
  //具体的代码实现中应该从数据库中查询了相关数据并调用了Collection类,下面看到这个类的时候会有一个了解
  //而且这个方法的实现应该放在子类中才对
  static function getCollection($type){   
    return array();
  }
  
  function collection(){
    return self::getCollection(get_class($this));
  }
  
}

class Venue extends DomainObject {
  private $name;
  private $spaces;
  
  function __construct ($id = null,$name=null){
    $this->name= $name;
    $this->spaces = self::getCollection('\\woo\\domain\\space'); //这里应该证明了我上述的猜测
    parent::__construct($id);
  }
  
  function setSpaces(SpaceCollection $spaces){
    $this->spaces = $spaces;
  }
  
  function addSpace(Space $space){
    $this->spaces->add($space);
    $space->setVenue($this);
  }
  
  function setName($name_s){
    $this->name = $name_s;
    $this->markDirty();
  }
  
  function getName(){
    return $this->name;
  }
}


//数据映射器(正如原文的解释数据映射器是一个负责将数据库数据映射到对象的类)
namespace woo\mapper;

abstract class Mapper{      //抽象基类
  abstract static $PDO;    //操作数据库的pdo对象
  function __construct (){
    if(!isset(self::$PDO){
      $dsn = \woo\base\ApplicationRegistry::getDSN();
      if(is_null($dsn)){
        throw new \woo\base\AppException("no dns");
      }
      self::$PDO = new \PDO($dsn);
      self::$PDO->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
    }
  }
  
  function createObject($array){          //将数组创建为上述领域模型中的对象
    $obj = $this->doCreateObject($array);    //在子类中实现
    return $obj;
  }
  
  function find($id){                //通过ID从数据库中获取一条数据并创建为对象
    $this->selectStmt()->execute(array($id));
    $array= $this->selectStmt()->fetch();
    $this->selectStmt()->closeCursor();
    if(!is_array($array)){
      return null;
    }
    if(!isset($array['id'])){
      return null;
    }
    $object = $this->createObject($array);
    return $object;  
  }
  
  function insert(\woo\domain\DomainObject $obj){      //将对象数据插入数据库
    $this->doInsert($obj);
  }
  
  //需要在子类中实现的各抽象方法
  abstract function update(\woo\domain\DomainObject $objet);
  protected abstract function doCreateObject(array $array);
  protected abstract function selectStmt();
  protected abstract function doInsert(\woo\domain\DomainObject $object);
}

//这里只建立一个VenueMapper类用于理解
class VenueMapper extends Mapper {
  function __construct (){    
    parent::__construct();  //各种sql语句对象  
    $this->selectStmt = self::$PDO->prepare("select * from venue where id=?");
    $this->updateStmt = self::$PDO->prepare("update venue set name=?,id=? where id=?");
    $this->insertStmt = self::$PDO->prepare("insert into venue (name) values(?)");
  }
  
  protected function getCollection(array $raw){    //将Space数组转换成对象
    return new SpaceCollection($raw,$this);      //这个类的基类在下面    
  }
  
  protected function doCreateObject (array $array){  //创建对象
    $obj = new \woo\domain\Venue($array['id']);
    $obj->setname($array['name']);
    return $obj;
  }
  
  protected function doInsert(\woo\domain\DomainObject $object){ //将对象插入数据库
    print 'inserting';
    debug_print_backtrace();
    $values = array($object->getName());
    $this->insertStmt->execute($values);
    $id = self::$PDO->lastInsertId();
    $object->setId($id);
  }
  
  function update(\woo\domain\DomainObject $object){    //修改数据库数据
    print "updation\n";
    $values = array($object->getName(),$object->getId(),$object->getId());
    $this->updateStmt->execute($values);
  }
  
  function selectStmt(){          //返回一个sql语句对象
    return $this->selectStmt;
  }
  
}

Iterator接口定义的方法:

rewind() 指向列表开头
current() 返回当前指针处的元素
key() 返回当前的键(比如,指针的指)
next()
valid()

下面这个类是处理多行记录的,传递数据库中取出的原始数据和映射器进去,然后通过数据映射器在获取数据时将其创建成对象


abstract class Collection implements \Iterator{
  protected $mapper;      //数据映射器
  protected $total = 0;    //集合元素总数量
  protected $raw = array();  //原始数据
  
  private $result;
  private $pointer = 0;    //指针
  private $objects = array();  //对象集合
  
  function __construct (array $raw = null,Mapper $mapper= null){
    if(!is_null($raw)&& !is_null($mapper)){
      $this->raw = $raw;
      $this->total = count($raw);
    }
    $this->mapper = $mapper;
  }
  
  function add(\woo\domain\DmainObject $object){  //这里是直接添加对象
    $class = $this->targetClass();
    if(!($object instanceof $class)){
      throw new Exception("This is a {$class} collection");
    }
    $this->notifyAccess();
    $this->objects[$this->total] = $object;
    $this->total ++;
  }
  
  abstract function targetClass();  //子类中实现用来在插入对象时检查类型的
  
  protected function notifyAccess(){  //不知道干嘛的
    
  }
  
  private function getRow($num){    //获取集合中的单条数据,就是这里通过数据映射器将数据创建成对象
    $this->notifyAccess();
    if($num >= $this->total || $num < 0){
      return null;
    }
    if(isset($this->objects[$num]){
      return $this->objects[$num];
    }
    if(isset($this->raw[$num]){
      $this->objects[$num] = $this->mapper->createObject($this->raw[$num]);
      return $this->objects[$num];
    }
  }
  
  public function rewind(){      //重置指针
    $this->pointer = 0;
  }
  
  public function current(){      //获取当前指针对象
    return $this->getRow($this->pointer);
  }
  
  public function key(){        //获取当前指针
    return $this->pointer;
  }
  
  public function next(){      //获取当前指针对象,并将指针下移  
    $row = $this->getRow($this->pointer);
    if($row){$this->pointer ++}
    return $row;
  }
  
  public function valid(){    //验证
    return (!is_null($this->current()));
  }
  
}

//子类
class VenueColletion extends Collection implements \woo\domain\VenueCollection{
  function targetClass(){
    return "\woo\domain\Venue";
  }
}


//客户端
$mapper = new \woo\mapper\VenueMapper();
$venue = $mapper->find(12);
print_r($venue);

$venue = new \woo\domain\Venue();
$venue->setName("the likey lounge-yy");
//插入对象到数据库
$mapper->insert($venue);
//从数据库中读出刚才插入的对象
$venue = $mapper->find($venue->getId());
print_r($venue);

//修改对象
$venue->setName("the bibble beer likey lounge-yy");
//调用update来更新记录
$mapper->update($venue);
//再次读出对象数据
$venue = $mapper->find($venue->getId());
print_r($venue);


//结束

相关推荐:

业务逻辑层之事务脚本与领域模型

以上就是PHP领域模型和数据映射器详解的详细内容,更多请关注php中文网其它相关文章!

  • 相关标签:PHP 详解 映射
  • 本文原创发布php中文网 ,转载请注明出处,感谢您的尊重!
  • 相关文章


  • PHP 随机数 C扩展随机数
  • PHP查询附近的人及其距离的实现方法_php技巧
  • php反射类ReflectionClass用法分析_php技巧
  • php+mysql实现的二级联动菜单效果详解_php技巧
  • PHP领域模型和数据映射器详解
  • 网友评论

    文明上网理性发言,请遵守 新闻评论服务协议

    我要评论
    独孤九贱(4)_PHP视频教程

    独孤九贱(4)_PHP视频教程

    江湖传言:PHP是世界上最好的编程语言。真的是这样吗?这个梗究竟是从哪来的?学会本课程,你就会明白了。 PHP中文网出品的PHP入门系统教学视频,完全从初学者的角度出发,绝不玩虚的,一切以实用、有用...

    • PeterZhu
    • 2017-03-20 22:47:17
    • 点击数(110037)

    独孤九贱(5)_ThinkPHP5视频教程

    独孤九贱(5)_ThinkPHP5视频教程

    ThinkPHP是国内最流行的中文PHP开发框架,也是您Web项目的最佳选择。《php.cn独孤九贱(5)-ThinkPHP5视频教程》课程以ThinkPHP5最新版本为例,从最基本的框架常识开始,将...

    • PeterZhu
    • 2017-05-16 12:03:57
    • 点击数(107850)

    独孤九贱(1)_HTML5视频教程

    独孤九贱(1)_HTML5视频教程

    《php.cn原创html5视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了HTML知识。 ...

    • PeterZhu
    • 2017-03-13 10:15:11
    • 点击数(82846)

    ThinkPHP5实战之[教学管理系统]

    ThinkPHP5实战之[教学管理系统]

    本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目。

    • PeterZhu
    • 2017-07-24 16:48:56
    • 点击数(82076)

    PHP入门视频教程之一周学会PHP

    PHP入门视频教程之一周学会PHP

    所有计算机语言的学习都要从基础开始,《PHP入门视频教程之一周学会PHP》不仅是PHP的基础部分更主要的是PHP语言的核心技术,是学习PHP必须掌握的内容,任何PHP项目的实现都离不开这部分的内容,通...

    • 小云云

      全栈工程师

    • 想不好签名了...
    • 5865篇
      文章总数
    • 184
      文章总浏览数

    相关视频教程

  • javascript初级视频教程 javascript初级视频教程
  • jquery 基础视频教程 jquery 基础视频教程
  • javascript三级联动视频教程 javascript三级联动视频教程
  • 独孤九贱(3)_JavaScript视频教程 独孤九贱(3)_JavaScript视频教程
  • 独孤九贱(6)_jQuery视频教程 独孤九贱(6)_jQuery视频教程
  • 相关视频章节