当前位置: 首页 > 文档资料 > FuelPHP 中文文档 >

CRUD - Orm 套件

优质
小牛编辑
118浏览
2023-12-01

Orm 是 物件关联对映(Object Relational Mapper) 的简写,它做两件事:
对应你资料库里的资料列到物件, 并能让你在这些物件之间建立关係。
它紧随 活动记录模式( Active Record Pattern),但也受到其他系统的影响。

CRUD:建立、读取、更新和删除

一旦你配置好你的模型,是时候开始在你的资料库中建立、读取、 更新和删除条目。

建立(Create)

// 选项 1
$new = new Model_Example();
$new->property = 'something';
$new->save();

// 选项 2,使用 forge 代替 new
$new = Model_Example::forge();
$new->property = 'something';
$new->save();

save() 之后,模型已经被储存到资料库, 而且如果你正在使用一个 auto_increment 主键,在成功储存后, 它将自动地被设定在实例。

你也可以在模型设定一个特性的阵列:

$props = array('property' => 'something');

// 使用 "new"
$new = new Model_Example($props);
$new->save();

// 选项 2,使用 forge 代替 new
$new = Model_Example::forge($props);
$new->save();

读取(Read)

或实际上是 find()。find 方法可用于三种方式:选找一个特定 ID(主键)、 寻找第一个/最后一个或带条件的所有条目。 所有可能的选择方法(where、or_where、order_by、等)可在页面底部找到。

Find by ID

// 你知道有一个主题是 ID=2
$entry = Model_Article::find(2);

// ……或当使用複合主键
$entry = Model_Article::find(array(2, 'foo'));

在这个範例中它将回传一个 Model_Article 的实例或 null 当 ID 找不到时。

Find first/last

// 寻找第一个条目
$entry = Model_Article::find('first');

// 寻找最后一个条目添加日期排序
$entry = Model_Article::find('last', array('order_by' => 'date'));

在这个範例中它将回传一个 Model_Article 的实例或 null 当 ID 找不到时。

Find all

// 寻找所有主题
$entry = Model_Article::find('all');

// 从 category 1 降序排列日期寻找所有主题
$entry = Model_Article::find('all', array(
	'where' => array(
		array('category_id', 1),
	),
	'order_by' => array('date' => 'desc'),
));

// 从 category 1 或 catergory 2 寻找所有主题
$entry = Model_Article::find('all', array(
	'where' => array(
		array('category_id', 1),
		'or' => array(
array('catergory_id', 2),
		),
	),
));

在这个範例中它将始终回传一个 Model_Article 实例的阵列。

Find 使用鍊结方法

你不能没带属性呼叫 find() 方法,或带 null 或一个包含 null 的变数做为参数来呼叫。如果你这样做,null 会被回传。如果你想要鍊结方法, 使用 query() 方法替代。

$query = Model_Article::query()->where('category_id', 1)->order_by('date', 'desc');

// 我们想知道给分页的主题总数
$number_of_articles = $query->count();

// 我们想知道最后一个发行的 ID
$number_of_articles = $query->max('id');

// 我们想知道第一个发布的主题的日期
$number_of_articles = $query->min('date');

// 取回一个 Article
$newest_article = $query->get_one();

// 我们重複使用但添加一个回传限制到上一个查询,来取回多个主题
$all_articles = $query->limit(15)->get();

这些方法全部都一样有效,其他四个 find 方法实际上一样使用 Query 物件, 但不回传。

部分行选择

预设情况下,所有 ORM find 方法会选择所有资料表行。你可以使用 select 阵列条目, 或 select() 方法来改变此行为。

// 使用阵列方法。只选择 'name' 和 'date' 行
$entry = Model_Article::find('last', array('select' => array('name', 'date')));

// 一样,但使用鍊结方法
$entry = Model_Article::query()->select('name', 'date')->get();

// 使用阵列方法。选择所有行除了 'date'
$entry = Model_Article::find('all', array('select' => array(array('date' => false))));

// 一样,但使用鍊结方法
$entry = Model_Article::query()->select(array('date' => false))->get();

更新(Update)

$entry = Model_Article::find(4);
$entry->title = 'My first edit';
$entry->author = 'Total n00b';
$entry->save();

就是这样,没有更多了:寻找、更改特性并储存。

你也可以在模型设定一个特性的阵列:

$entry = Model_Article::find(4);
$entry->set(array(
	'title'  => 'My first edit',
	'author' => 'Total n00b'
));

$entry->save();

删除(Delete)

$entry = Model_Article::find(4);
$entry->delete();

再一次,没有更多了:寻找并删除。

在上一个例子中,$entry 变数及其物件仍然存在。 但主键设为 null 而且该物件本身被认为是一个新的实例。 如果你在删除之后储存,它会重新被输入到资料库并被赋予一个新的主键, 在 auto_increment 被开启时。

使用 find 时所有的选择方法

方法参数範例
select字串 $column, [字串 $more_columns,] | 阵列 $filter
// 只寻找一些行
Model_Article::query()->select('id', 'name');
Model_Article::find('all', array('select' => array('id', 'name')));

// 寻找所有行除了 'name'
Model_Article::query()->select(array('name' => false));
Model_Article::find('all', array('select' => array(array('name' => false))));
related字串|阵列 $relation, [阵列 $conditions]
// 在 find 中包含关联模型
Model_Article::query()->related(array('author', 'comments'));
Model_Article::find('all', array('related' => array('author', 'comments')));

//=============================
// 在关联包含一个或更多条件(只支援鍊结)
//=============================

// 第一种方法 - 使用一个阵列
//----------------------------
// 单一条件
Model_Article::query()
    ->related('author', array('where' => array(array('active', '=', 1))));

// 多个条件
Model_Article::query()
    ->related('author', array('where' => array(array('active', '=', 1), array('status', '=', 'X'))));

// 第二种方法 - 使用句点表示法
//----------------------------
// 单一条件
Model_Article::query()
	->related('author')
	->where('author.active', 1);

// 多个条件
Model_Article::query()
	->related('author')
	->where('author.active', 1);
	->where('author.status', 1);
use_view字串 $viewname
// 使用 view 来检索资料
Model_Article::query()->use_view('with_comments');
Model_Article::find('all', array('use_view' => 'with_comments'));
where字串 $column, [字串 $operator,] 混合 $value
// 单一 where
Model_Article::query()->where('id', 4);
Model_Article::find('all', array('where' => array('category_id' => 5)));

// 多个 where 用法範例
Model_Article::query()->where('id', 4)->where('category_id', '>', 1);
Model_Article::query()->where(array('id' => 4, 'category_id' => 6));
Model_Article::find('all', array('where' => array(array('category_id', '=', 5), array('publish', '<', time()))));

// 使用 or where
Model_Article::query()->where('id', 4)->or_where('id', 5);
order_by字串 $column, [字串 $direction]
// 单一 order_by
Model_Article::query()->order_by('name', 'desc');
Model_Article::find('all', array('order_by' => array('name' => 'desc')));

// 多个 order_by 用法範例
Model_Article::query()->order_by('name', 'desc')->order_by('category_id', 'asc');
Model_Article::query()->order_by(array('name' => 'desc', 'category_id' => 'asc'));
Model_Article::find('all', array('order_by' => array(array('name' => 'desc', 'category_id' => 'asc'))));
from_cache布林$cache
// 在此查询停用 ORM 物件快取
Model_Article::query()->from_cache(false);
Model_Article::find('all', array('from_cache' => false));
limit整数 $limit
// 带有关联一致的 limit
Model_Article::query()->limit(10);
Model_Article::find('all', array('limit' => 10));
rows_limit整数 $limit
// 没有关联一致的 limit
Model_Article::query()->rows_limit(10);
Model_Article::find('all', array('rows_limit' => 10));
offset整数 $offset
// 带有关联一致的 offset
Model_Article::query()->offset(10);
Model_Article::find('all', array('offset' => 10));
rows_offset整数 $offset
// 没有关联一致的 offset
Model_Article::query()->rows_offset(10);
Model_Article::find('all', array('rows_offset' => 10));

不要把 limit/offset 两种类型搞混了!limitrows_offset 的组合(或其他方式), 将导致意想不到的结果!

在此情境中,关联一致意指预设情况下,当你查询包含关联模型时, ORM 将确保关联结果是一致的。这意味着你的结果并非总是准确的被限制。 例如,如果第一个 parent 在结果有 12 个 children,你的结果集将包含 12 笔纪录, 即使你已经使用 limit(10)。当你使用 rows_limit(10),该结果集将只包含 10 笔资料, 但将缺少 2 笔关联纪录,而且稍候不能被检索,因为该结果将被快取, 而且快取处理程序并不知道该结果是不完整的!

複杂的 where 子句

使用鍊结你可以建立更複杂的 where 子句,使用 and、or 及巢状

// 複杂的 where 子句
Model_Article::query()
  ->where('author', '=', 16)
  ->and_where_open()
      ->where('date', '<', time())
      ->or_where('draft', '=', 1)
  ->and_where_close();

// 建立 WHERE `author` = 16 AND (`date` < 1348404127 OR `draft` = 1)

要建立巢状的 OR,使用 or_where_open()or_where_close()。 务必确保你的 open 和 close 方法相配!

子查询

子查询可以透过建构一个独立的查询物件来建立,并使用 get_query() 来解析它。

$subQuery = Model_Article::query()
        ->select('author')
        ->where('date', '<', time())
        ->where('draft', '=', 1);

Model_Article::query()
        ->where('author', '=', 16)
        ->or_where('author', $subQuery->get_query(true))
        ->get();

自订 SQL

执行自订 SQL 语句并让结果回传做为一个 Orm 模型(或模型的列表)也是可能的。虽然这不是 Orm 本身的一部分,知道它是有用的。更多资讯先看看 DB::query() 函式。

DB::query('SELECT * FROM `articles` WHERE `id` = 1')->as_object('Model_Article')->execute();

建议你在有可能的情况下使用 query() 函式