tabusoft/orm

简单的ORM和实体管理器

2.0.6 2020-06-17 13:00 UTC

README

Tabusoft/ORM是一个实体和关系管理器。

  • 只需使用命令行脚本来简单地创建实体和仓库
  • 帮助你基于查询构建实体。你将使用实体来获取实体,不需要将查询输出转换为实体!
  • 将映射表与表之间所有的外键关系,帮助你编写查询,或者简单地延迟加载相关实体。

安装

您可以使用composer安装它

$ composer require tabusoft/orm

使用实体管理器

要使用实体管理器,我们必须创建所有实体和仓库。这两个词的意义将在下一段中解释。我们有两个命令行工具:orm-cli和create-config。

创建config.json

create-config可用于创建config.json文件,供orm-cli使用。

$ ./create-config --mysql --host=localhost --user=root --password=password --port=3306 --database-name=mydb --output-file=destination.json --output-type=json

您可能需要指定许多配置选项。请参阅帮助文档

$ ./create-config --help

创建实体

实体对象是数据库表或集合的1对1描述。类存储在选定的命名空间下的"Entities"目录中。实体类使用一个包含所有属性和setter、getter的Trait。仓库用于管理数据库持久性,并存储在选定的命名空间下的"Repositories"文件夹中。仓库类使用一个包含所有持久性信息的Trait。

要创建这些文件,您可以使用:orm-cli

$ ./orm-cli install config.json 

仅更新"描述符",而不更改用户编辑的实体

$ ./orm-cli update config.json 

实体限制

一些关于在MySQL数据库上创建表的提示。

  • 表必须有一个作为主键的id列。
  • 如果您有一个视图,则视图必须有一个唯一的id列。在创建时请明智地操作。
  • 关系将通过外键创建。您可以在之后创建自己的关系。
  • 仓库可以使用不同的数据库。但是,您不能在具有不同数据库的主机或端口的EQB表之间进行连接。

使用实体

例如,您将创建这些实体:(将在下面的示例中使用)

<?php

namespace Application\Entities;

use Tabusoft\ORM\Entity\EntityAbstract;
use Application\Entities\Descriptors\ForumCategoryDescriptor;

/**
*
* @database test_forum
* @table forum_category
*
**/
class ForumCategory extends EntityAbstract
{
    use ForumCategoryDescriptor;

    /** implements here your class methods */

}
?>
<?php

namespace Application\Entities;

use Tabusoft\ORM\Entity\EntityAbstract;
use Application\Entities\Descriptors\ForumTopicsDescriptor;

/**
*
* @database test_forum
* @table forum_topics
*
**/
class ForumTopics extends EntityAbstract
{
    use ForumTopicsDescriptor;

    /** implements here your class methods */

}
?>

初始化实体

tabusoft/orm在工厂配置中大量使用tabusoft/db。您需要提供与表相同的配置。请参阅该包的文档

您可以像对象一样实例化它

//init the tabusoft/db 
$db_config = new \Tabusoft\DB\DBFactoryConfig("localhost","test","test_username","test_password");
\Tabusoft\DB\DBFactory::getInstance($db_config);

//empty object
$category = new Application\Entities\Category();

或从数据库中检索它

//obtain the repository
$repo = Application\Entities\ForumCategory()::getRepository();

//or
$repo = new Application\Repository\ForumCategoryRepository();

$category = $repo->findById(1323);

保存(插入或更新)实体

实体管理器使用MySQL REPLACE命令在数据库中插入或更新行。您只需更改实体属性并通过其仓库保存即可。

$category->setCategoryName("New Category name");
$repo->save($category);

如果您正在保存新的Category对象,则必须填写所有非空列。否则,您将收到一个\Exception。

延迟加载

当您不需要性能时,可以使用外键关系简单地调用对象。在下一个示例中,我们有从ForumTopics到ForumCategory的关系。延迟加载方法直接出现在实体描述符中。

$topics = ForumTopics::getRepository()->findBy("id",[1,2,3,4]);

foreach($topics as $topic) {
    dump($topic);

    $category = $topic->getForumCategory();

    dump($category);
}

每次您调用getForumCategory()方法时,都会有一个查询。结果将被缓存。请注意,如果您将使用多个请求。

使用查询构建器

EQB是实体查询构建器。它为您提供了不深入数据库结构(如果愿意)就可以进行查询的可能性。它有3个特殊类:EQB::Entity,EQB::Column,EQB::Function。

实体

包装实体类,以便在查询中使用。

将属性映射到列。如果您在select中使用单个列,则必须指定别名。

函数

将 MySQL 属性映射到类工具。如果您要在 SELECT 语句中使用它,您需要指定一个别名。

综合起来:查询

EQB 对象相当于 SQL 查询。

简单选择

让我们把它们放在一起

//init the query object
$query = new EQB();

//init two EQBEntity refered to the relative Entities class.
$fc = new EQBEntity(ForumCategory::class);
$ft = new EQBEntity(ForumTopics::class);

//doing a select:
//this will return two result containing:
//a ForumCategory entity, a ForumTopic entity, 
//and the id column of forum category enitity. 
$query = $q->select( $ft, $fc, $fc->id->as("id") );
$query->from($ft);
$query->where($fc->id, "IN (?)")->pushValue([1,2]);
$res = $query->query();

//or in the short mode:
$res = $q->select( $ft, $fc, $fc->id->as("id") )
            ->from($ft);
            ->where($fc->id, "IN (?)");
            ->query([1,2]);

//res is a traversable collection of: [ ForumTopic object, ForumCategory Object, id  ]
foreach($res as $r){
    var_dump($r);
}

完整的 JOIN 解释

要创建 JOIN

$q = $q->select($ft,$fc)
    ->from($ft)
    ->join($fc, 'ON', $ft->idCategory, '=', $fc->id)

MySQL 函数

$q = $q->select(EQBFunction::COUNT('*')->as('num'))
    ->from($ft)
    ->leftjoin($fc)
    ->where(EQBFunction::ISNULL($fc->id);

快速 JOIN

如前所述,我们正在映射外键关系。在这种模式下,我们可以创建简单的 JOIN。对于每个 JOIN,我们将在 FROM 和之前的 JOIN 中搜索相关的实体。如果没有关系,我们将向相反方向搜索。在这种情况下,第一个关系获胜。

$q = $q->select(*)
    ->from($ft)
    ->join($fc);