pete-robinson/super-simple-orm

适用于需要轻微数据库层的项目的超级简单ORM。

dev-master 2016-07-15 11:59 UTC

This package is not auto-updated.

Last update: 2024-09-20 19:09:24 UTC


README

一个从PDO扩展而来的超级简单ORM,适用于需要轻微数据库层的项目。

这个ORM基本上允许你在需要简单数据库交互,可能不想使用像Doctrine这样的更强大解决方案的项目中实现简单的ORM层。

架构

数据中的每个表都必须有对应的实体和仓库类。与其他ORM一样,实体代表数据的单个实例,而仓库以集合的形式处理数据(即实体 = 一辆车。仓库 = 多辆车)。

工厂类用于获取仓库,它将为请求的数据结构返回一个仓库实例。

实体类必须被编写并传递给仓库类,以便持久化到数据库。

使用方法

每个数据结构都需要一个实体和一个仓库类。

要创建实体,你必须实现SuperSimple\ORM\Entity\EntityInterface接口。实体类基本上由你的数据结构的getters和setters组成。

<?php
/**
 * Cd entity
 **/
namespace MyApp\ORM\Entity;
use SuperSimple\ORM\Entity\EntityInterface;

class Cd implements EntityInterface
{
	/**
	 * id
	 * @var int
	 **/
	private $id;

	/**
	 * name
	 * @var string
	 **/
	private $name;

	/**
	 * slug
	 * @var string
	 **/
	private $slug;

	/**
	 * get id
	 * @return int
	 **/
	public function getId()
	{
		return $this->id;
	}

	/**
	 * set id
	 * @param int $id
	 * @return self
	 **/
	public function setId($id)
	{
		$this->id = $id;
		return $this;
	}

	/**
	 * get slug
	 * @return string
	 **/
	public function getSlug()
	{
		return $this->slug;
	}

	/**
	 * set slug
	 * @param string $slug
	 * @return self
	 **/
	public function setSlug($slug)
	{
		$this->slug = $slug;
		return $this;
	}

	/**
	 * get name
	 * @return string
	 **/
	public function getName()
	{
		return $this->name;
	}

	/**
	 * set name
	 * @param string $name
	 * @return self
	 **/
	public function setName($name)
	{
		$this->name = $name;
		return $this;
	}

}

要创建仓库,你必须扩展SuperSimple\ORM\Repository\AbstractRepository并实现SuperSimple\ORM\Repository\RepositoryInterface。每个仓库类都必须有一个处理数据结构的持久化方法,以及一个将结果映射到对象的mapData方法。在未来,我将把这个责任抽象到库本身,而不是用户添加的类中。

<?php
/**
 * Cd repository
 **/
namespace MyApp\ORM\Repository;

use SuperSimple\ORM\Entity\EntityInterface;
use SuperSimple\ORM\Repository\AbstractRepository;
use SuperSimple\ORM\Repository\RepositoryInterface;
use MyApp\ORM\Entity\Cd;

class CdRepository extends AbstractRepository implements RepositoryInterface
{
	/**
	 * table name constant
	 * @var string
	 **/
	const TABLE_NAME = 'cds';

	/**
	 * persist
	 * @param object Page $entity
	 * @return void
	 **/
	public function persist(EntityInterface $entity)
	{
		// prepare query
		$query = $this->prepare('INSERT INTO ' . self::TABLE_NAME . ' (slug, name) VALUES (:slug, :name)');

		// bind slug and name
		$query->bindParam('slug', $entity->getSlug());
		$query->bindParam('name', $entity->getName());
		
		return $this->save($query);
	}

	/**
	 * map data
	 * @param mixed $data
	 * @return mixed
	 **/
	public function mapData($data, $singular = false)
	{
		// init return variable
		$return = false;

		if($data) {
			// if singular response required
			if($singular) {
				// instantiate new object
				$return = new Cd;
				// map data
				$return
					->setId($data['id'])
					->setSlug($data['slug'])
					->setName($data['name'])
				;
			} else {
				// array to map, not singular
				$return = array();
				foreach($data as $key => $entity) {
					$return[$key] = new Cd;
					$return[$key]
						->setId($entity['id'])
						->setSlug($entity['slug'])
						->setName($entity['name'])
					;
				}
			}
		}

		return $return;
	}

}

获取数据

从仓库获取和请求数据

use SuperSimple\ORM\Factory;

// init factory
$factory = new Factory([
	'dsn' => /*...*/,
	'username' => /*...*/
	'password' => /*...*/
]);

// fetch all - requires namespace (minus Repository element)
// returns a mapped array of Cd entity objects
$results = $factory->fetch('MyApp\ORM:Cd')->findAll();

// optional ordering (field => order)
$results = $factory->fetch('MyApp\ORM:Cd')->findAll([
	'name' => 'ASC'
]);

// optional result limiting (10 in this example)
$results = $factory->fetch('MyApp\ORM:Cd')->findAll(false, 10);

// fetch one (by ID)
// returns an object of requested entity if data exists
$results = $factory->fetch('MyApp\ORM:Cd')->find($id);

处理实体

探索数据

实体代表了数据结构中填充到实体对象的数据。

use SuperSimple\ORM\Factory;

// init factory
$factory = new Factory([
	'dsn' => /*...*/,
	'username' => /*...*/
	'password' => /*...*/
]);

// find one entity
$cd = $factory->fetch('MyApp\ORM:Cd')->find($id);

echo $cd->getId();
echo $cd->getName();
echo $cd->getSlug();

持久化

use SuperSimple\ORM\Factory;
use MyApp\ORM\Entity\Cd;

// init factory
$factory = new Factory([
	'dsn' => /*...*/,
	'username' => /*...*/
	'password' => /*...*/
]);

// find one entity
$repo = $factory->fetch('MyApp\ORM:Cd');

// create a new data object
$new_cd = new Cd;
$new_cd
	->setName('Artist Name')
	->setSlug('artist-name')
;

// save to database
$repo->persist($new_cd);

限制

  1. 需要实现一个更安全的排序方法。目前直接从输入参数构造,因为PDO不喜欢使用作为绑定参数的排序参数
  2. 需要实现一个更让开发者友好的方法,让库理解数据结构,而不是通过RepositoryInterface::mapData来定义它们
  3. 不支持更新或删除 - 仅检索和持久化