适用于 PHP 5.5+ 的 DataMapper ORM

安装数: 2,300

依赖者: 0

建议者: 0

安全: 0

星级: 1

关注者: 2

分支: 14

语言:C

v1.0.17 2014-11-30 06:46 UTC

README

适用于关系数据库和 MongoDB

Build Status

连接到数据库

Spot\Config 对象通过名称存储和引用数据库连接。创建一个新的 Spot\Config 实例,并添加 Spot 之外创建的数据库连接。这是为了允许您的应用程序创建原始 PDO 连接并重新使用它。我一直以来最大的抱怨是,几乎每个 ORM/Model 类都希望为您创建这个,而不是传递这个连接。

// PostgreSQL
$db = new Pdo('pgsql:host=localhost;dbname=jdoe', 'jdoe', 'mypass');

$cfg = \Spot\Config::getInstance();
$adapter = $cfg->addConnection('db', new \Spot\Adapter\Pgsql($db));

$adapter = $cfg->connection('db');

访问 Mapper

由于 Spot 遵循 DataMapper 设计模式,您将需要一个 mapper 实例来处理对象实体和数据库表。

$mapper = new \Spot\Mapper($cfg);

由于您必须在任何使用数据库的地方都能访问到您的 mapper,大多数人会创建一个辅助方法来创建一个 mapper 实例一次,并在需要时再次返回同一个实例。这样的辅助方法可能看起来像这样

function get_mapper() {
    static $mapper;
    if($mapper === null) {
        $mapper = new \Spot\Mapper($cfg);
    }
    return $mapper;
}

或者如果您在框架中有一个 Registry 类

$registry = Registry::getInstance();
$registry->set('mapper', $mapper);

$mapper = Register::get('mapper');

或者使用依赖注入容器

$di->setShared('mapper', $mapper);

$mapper = $di->getShared('mapper');

创建实体

实体类可以按照您在项目结构中设置的任意名称和命名空间命名。对于以下示例,实体将仅使用 Entity 命名空间作为前缀,以便易于 psr-0 兼容的自动加载。

namespace Entity;

class Post extends \Spot\Entity
{
    protected static $datasource = 'posts';

    public static function fields()
    {
        return array(
            'id' => array('type' => 'int', 'primary' => true, 'serial' => true),
            'title' => array('type' => 'string', 'required' => true),
            'body' => array('type' => 'text', 'required' => true),
            'status' => array('type' => 'int', 'default' => 0, 'index' => true),
            'date_created' => array('type' => 'datetime')
        );
    }

    public static function relations()
    {
        return array(
            // Each post entity 'hasMany' comment entites
            'comments' => array(
                'type' => 'HasMany',
                'entity' => 'Entity_Post_Comment',
                'where' => array('post_id' => ':entity.id'),
                'order' => array('date_created' => 'ASC')
            )
        );
    }
}

另一个实体示例,一个位于应用程序 Model 命名空间中的模型类。这是最简单的定义,仅定义了模型字段。

<?php
namespace Blog\Model;
use \Spot\Entity;

class Game extends Entity
{
	protected static $datasource = 'game';

	public static function fields()
	{
		return array(
			'id' => array('type' => 'int', 'primary' => true, 'serial' => true),
			'status_id' => array('type' => 'int', 'default' => 0, 'index' => true),
			'date_created' => array('type' => 'datetime', 'default' => date('Y-m-d h:m:i'), 'required' => true),
			'image_count' => array('type' => 'int', 'default' => 0, 'index' => true),
			'name' => array('type' => 'string', 'required' => true),
			'slug' => array('type' => 'string', 'required' => true),
		);
	}
}

内置字段类型

所有基本字段类型都已内置,并提供所有默认功能

  • 字符串
  • 整数
  • 浮点数/双精度/十进制
  • 布尔值
  • 文本
  • 日期
  • 日期时间
  • 时间戳
  • 年份
  • 月份
  • 日期

注册自定义字段类型

如果您想在 get/set 上注册具有自定义功能的自定义字段类型,请查看 Spot\Type 命名空间中的类,创建自己的类,并在 Spot\Config 中注册它

$this->setTypeHandler('string', '\Spot\Type\String');

关系类型

实体关系类型包括

  • HasOne
  • HasMany
  • HasManyThrough

查找器(Mapper)

最常用的查找器是 all,用于返回实体集合,以及 firstget,用于返回符合条件的一个实体。

all(entityName, [conditions])

查找所有符合给定条件的 entityName,并返回一个包含加载的 Spot\Entity 对象的 Spot\Entity\Collection

// Conditions can be the second argument
$posts = $mapper->all('Entity\Post', array('status' => 1));

// Or chained using the returned `Spot\Query` object - results identical to above
$posts = $mapper->all('Entity\Post')->where(array('status' => 1));

// Or building up a query programmatically
$posts = $mapper->all('Entity\Post');
$posts->where(array('date_created :gt', date('Y-m-d'));

... // Do some checks

$posts->limit(10);

由于返回了一个 Spot\Query 对象,因此可以在任何顺序和方式中链接条件和其它语句。查询将在迭代或 count 时懒执行,或者可以通过在链尾调用 execute() 来手动执行。

first(entityName, [conditions])

查找并返回一个符合标准的单个 Spot\Entity 对象。

$post = $mapper->first('Entity\Post', array('title' => "Test Post"));

遍历结果

// Fetch mapper from DI container
$mapper = $di->getShared('mapper');

// Get Query object to add constraints
$posts = $mapper->all('Entity\Posts');

// Find posts where the commenter's user_id is 123
$posts->where(array('user_id :eq', 123));

// Only get 10 results
$limit = (int) $_POST['limit'];
$posts->limit($limit);

// Loop over results
foreach ($posts as $post) {
	echo "Title: " . $post->title . "<br>";
	echo "Created: " . $post->date_created . "<br>";
}