granadaorm/granada

支持预加载、延迟加载的 Active Record / ORM

4.0.0 2024-09-09 06:27 UTC

README

Latest Stable Version Total Downloads Build Status

Granada 是一个易于使用的 Active Record 实现,基于 Idiorm/Paris 的 ORM。

快速浏览

use Granada\Model;

class User extends Model
{
    public function posts() {
        return $this->has_many('Post');
    }
}

class Post extends Model {}

// select
$user = User::where('name', 'John')->find_one();

// modify
$user->first_name = 'Doe';
$user->save();

// select relationship
$posts = $user->posts()->find_many();
foreach ($posts as $post) {
    echo $post->content;
}

您可以在 paris.readthedocs.org 阅读Paris文档,但请务必阅读以下补充内容。

安装

使用 composer

composer require granadaorm/granada

配置

require 'vendor/autoload.php';

use Granada\ORM;

ORM::configure('mysql:host=localhost;dbname=my_database');
ORM::configure('username', 'database_user');
ORM::configure('password', 'top_secret');

如常,您可以在 Paris 文档 中详细了解。

补充

预加载

您可以使用 "with" 方法将关系预加载添加到查询中。

$results = User::with('avatar', 'posts')->find_many();

将使用3个查询来获取用户及其关系

SELECT * FROM user
SELECT * FROM avatar WHERE user_id IN (....)
SELECT * FROM posts WHERE user_id IN (....)

您可以按这种方式为每个结果获取关系的查询结果

foreach($results as $result){
    echo $result->avatar->img;
    foreach($result->posts as $post){
        echo $post->title;
    }
}

延迟加载

尝试访问尚未获取的关系将调用并返回它

$results = User::find_many();
foreach($results as $result){
    echo $result->avatar->img;
}

注意,如果在上面的示例中没有 "avatar" 的结果,它将抛出 Notice: Trying to get property of non-object... 注意:可能值得为此用例和其他用例创建一个 NULL 对象。

带有预加载参数的链式关系

您可以链式调用关系并为关系调用添加参数

// chained relationships with dot notation
$results = User::with('posts.comments')->find_many();

// OR

// chained relationships use the "with" reserved word. (usefull if you want to pass arguments to the relationships)
$results = User::with(array('posts'=>array('with'=>array('comments'))))->find_many();

// SELECT * FROM user
// SELECT * FROM post WHERE user_id IN (....)
// SELECT * FROM comments WHERE post_id IN (....)

foreach($results as $result){
    foreach($posts as $post){
        echo $post->title;
        foreach($post->comments as $comment){
        echo $comment->subject;
        }
    }
}

// you can use arguments (one or more) to call the models relationships
$results = User::with(array('posts'=>array('arg1')))->find_many();
// will call the relationship defined in the user model with the argument "arg1"

自定义查询过滤器

可以在模型上创建静态函数作为查询中的过滤器。以 "filter_" 开头

use Granada\Model;

class ModelName extends Model {
    ....
    public static function filter_aname($query, $argument1, $argument2...){
        return $query->where('property', 'value')->limit('X')......;
    }
    ....
}

并在静态调用中使用它

ModelName::aname($argument1, $argument2)->....

Granada 的多个补充名称

  • select_raw
  • group_by_raw
  • order_by_raw
  • raw_join
  • insert : 从数组创建并保存多个元素
  • pluck : 从结果返回单个列。
  • find_pairs : 返回键=>值的数组作为结果
  • save : 接受一个布尔值以使用 "ON DUPLICATE KEY UPDATE"(仅适用于 Mysql)
  • delete_many (接受连接子句)

重载 SET

// In the Model
protected function set_title($value)
{
    $this->alias = Str::slug($value);
    return $value;
}
// outside of the model
$content_instance->set('title', 'A title');

// works with multiple set too
$properties = array(
    'title'   => 'A title',
    'content' => 'Some content'
);
$content_instance->set($properties);

// try it with a direct assignement
$content_instance->title = 'A title';

重载 GET 和缺失属性

// In the Model

// Work on defined
protected function get_path($value)
{
    return strtolower($value);
}

// and non-defined attributes.
protected function mising_testing()
{
    return 'whatever';
}
...

// outside of the model
echo $content_instance->path; // returns the lowercase path value of $content_instance
echo $content_instance->testing; // returns 'whatever' since we defined a missing_{attribute_name}

当然,您仍然可以定义具有属性名称的函数以完全重载它。

在模型上定义 resultSet(集合类型)类

现在可以定义模型实例结果返回的 resultSet 类。 (如果 return_result_sets 配置变量设置为 true)请注意,定义的 resultSet 类必须 extends Granada\ResultSet 并必须加载

// In the Model
public static $resultSetClass = 'TreeResultSet';
// outside of the model
var_dump(Content::find_many());

// echoes
object(TreeResultSet)[10]
    protected '_results' => array(...)
....

ResultSet 由模型在结果中定义,如您在上面所见。在预加载时,结果是一致的。例如,如果我们有一个 Content 模型,具有 $resultSetClass = 'TreeResultSet' 和一个 has_many 关系定义为 media

Content::with('media')->find_many();

将返回一个包含 Content 实例的 TreeResultSet,每个实例都有一个包含 Granada\ResultSetproperty $media(如果没有在模型上定义,则为默认的 resultSet)

基本文档来自 Paris

Paris

功能完整

自 1.4.0 版本起,Paris 被认为功能完整。虽然它将继续通过错误修复进行维护,但不会添加更多新功能。

PHP5 的轻量级 Active Record 实现。

建立在 Idiorm 之上。

在 PHP 5.2.0+ 上进行了测试 - 可能可以使用 PDO 和正确的数据库驱动程序在更早的版本上运行。

BSD 许可证 下发布。

功能

  • 极其简单的配置。
  • 公开了Idiorm流畅查询API的全部功能。Idiorm
  • 支持关联。
  • 简单的机制来封装常用的查询在过滤器方法中。
  • 基于PDO构建。
  • 始终使用预处理语句,以防止SQL注入攻击。
  • 数据库无关性。目前支持SQLite、MySQL、Firebird和PostgreSQL。可能支持其他数据库,请尝试一下!
  • 支持通过方法链对模型集合进行过滤或一次性对多个结果应用操作。
  • 支持多个连接。

历史

Granada最初由Erik Wiesenthal开发,版本为1.5。进一步的开发由Josh Marshall开始,以发布版本2.0。