ORM实例–kohana3使用手册
对象关系映射(Object Relational Mapping 简称ORM)允许你把数据库中的数据
当成一个PHP对象来操纵和控制。一旦你定义了ORM和你的数据库中数据的关系,那么无论你用任何你喜欢的方式操纵数据,以及保存结果到数据库,都不需要使用SQL语言。通过创建按照配置约定的模型之间的关系,大部分从数据库中重复的编写创建,读取,更新和删除信息的查询可以被减少或者完全消除。所有的关系都能被自动用ORM库来处理并且你可以像使用标准对象属性一样访问相关数据。
注意:请确定你使用了最新的 3.0.* 来处理,
最新的版本可以访问 http://dev.kohanaphp.com/projects/kohana3/files
启用
第一步是 启用并配置 数据库(database)模块
Orm模块被包括在 Kohana3.0安装程序中。但是在你使用前需要你去启用它。
在你的 application/bootstrap.php 文件中修改调用的 Kohana::modules() 方法,按照下面的示例来包含 orm 模块。
Kohana::modules(array( 'userguide' => MODPATH.'userguide', 'database' => MODPATH.'database', 'orm' => MODPATH.'orm', // orm access ));
没有必须的配置文件
定义模型 简单
如果你的数据库和名称约定( 在v2 版本的文档中有提到)匹配并且你不使用pdo链接,模型可以像这样简单的定义:
class Model_Account extends ORM
{ }
定制
一些基本模型属性的定义:
class Model_Account extends ORM
{
protected $_db = 'default'; //或者其他配置中定义的数据组n
protected $_table_name = 'strange_tablename'; // 默认: accounts
protected $_primary_key = 'strange_pkey'; // 默认: id
protected $_primary_val = 'strange_name'; // 默认: name (作为主键(primary)的值)
// $_table_columns的默认值: 使用数据库自动检查来寻找列和信息
// 查看所有可能的列属性http://v3.kohanaphp.com/guide/api/Database_MySQL#list_columns
protected $_table_columns = array(
'column_name' => array('data_type' => 'int', 'is_nullable' => FALSE),
'column_name2' => array('data_type' => 'string', 'is_nullable' => TRUE),
);
// 这里提到的字段(field)能像属性一样访问,但是并不会被写操作引用
protected $_ignored_columns = array(
'helper_field',
);
}
注意:在这里的Kohana 3.0.3中,当 table_prefix在数据库配置中设置就是一个bug。你应该避免使用这个设置直到 3.0.4
定义关联
查看 jheathco’s repo wiki 来了解定义关联的详细情况
加载
你可以使用ORM::factory方法或者ORM::__construct来创建一个模型实例:
$user = ORM::factory(‘user’);
// 或者
$user = new Model_User();
构造器和工厂方法也接受一个主键值用来加载给定的模型数据:
// 加载ID 5 的用户
$user = ORM::factory(‘user’, 5);
ORM::loaded 检查给定的模型是否已经成功加载。
延迟加载
3.0 ORM 实际上并不加载模型的数据,直到它是绝对必要时。这并不像以前的ORM版本。例如,如果你执行下列操作:
$user = ORM::factory(‘user’, 1); $user->name = ‘Joe’; $user->save();
上面的阿迪表仅仅有一个数据库查询,就是更新了主键记录为1。在加载模型数据时并没有执行。模型数据仅仅在它需要提高性能和限制数据库开销的时候才被加载。
echo $user->name 会,另一方面,迫使该模型数据加载。
写简单插入和更新
$user = ORM::factory('user', 1);
$user->name = 'Joe';
$user->save();
如果要附加必要的插入/更新的逻辑到保存,你可以覆盖你的模型中的save()函数并使用相同的方法测试ORM来确定你的插入或更新。
public function save()
{
// 如果它是一个插入...
if ($this->empty_pk()
|| isset($this->_changed[$this->_primary_key])) {
... do insert logic ...
}
else {
.. do update logic ...
}
return parent::save();
}
你可以使用 ORM::save_all 方法来更新多条记录。
$user = ORM::factory('user');
$user->name = 'Bob';
// 将所有动态记录的name改为Bob
$user->where('active', '=', TRUE)->save_all();
ORM::saved 检查所给的模型是否已经保存
(了解请看 http://github.com/kohana/userguide/blob/master/guide/tutorials.orm.md)
删除
删除记录
使用 ORM::delete 和 ORM::delete_all 来删除记录。这些方法和上面描述的save使用同样的异常方式,ORM::delete只接受一个可选的参数,也就是要删除的记录的id
(了解请看 http://github.com/kohana/userguide/blob/master/guide/tutorials.orm.md)
使用数据库表达式来写
分配到列的所有值都有写查询保护来防止sql注入溢出。如果必须要指定一个数据库列表达式的结果,使用DB::expr()
$user = ORM::factory('user', 1);
$user->name = 'Joe';
$user->last_modified = DB::expr('now()');
$user->modified_count = DB::expr('modified_count + 1');
$user->save();
警告:如果表达式涉及到用户输入,你要自己负责溢出。
模型验证(Validation)
你可以使用 $_rules,$_filters和$_callbacks属性(查看 validation文档))来列出规则,过滤器和回调函数。什么是模型中定义规则的最佳做法以及如何验证它们,这是一个很 热门的话题。
你决定。
class Model_Account extends ORM
{
...
protected $_rules = array(
'name' => array('not_empty' => null),
'website' => array('url' => null),
'zip' => array('regex' => array('/^\d{5}(\-\d{4})?$/')),
'phone_num' => array('phone' => array(array(10,11,14))),
);
protected $_filters = array(TRUE => array('trim' => NULL));
protected $_callbacks = ... refer to validation docs
protected $_labels = array(
'column_name' => 'pretty name',
);
}
用法:
$user = ORM::factory('user', 1);
$user->name = 'Joe';
$user->values($_POST);
if ($user->check()) {
$user->save();
} else {
$errors = $user->errors();
}
针对非模型字段的验证
有时你需要一个模型字段和独立表单字段(就像迫使两个密码或者email字段匹配)的规则参考。
对于那些谁都希望能在模型中定义规则(不是将这些验证放在控制器中),你需要在$_ignored_columns中注册一个外部字段使模型验证能访问它。
class Model_User extends ORM
{
$_ignored_columns = array(
'password_confirm',
);
protected $_rules = array(
'password_confirm' => array('not_empty'=> null),
'password' => array('not_empty' => null, 'matches', array('password_confirm')),
);
}
读
注意,如果你还不明白 Database库的查询生成器,你可以这样开始,这个库里有如此多关于orm的可用的函数。(查看$_db_methods属性来获得被支持的函数调用的完整列表)。
使用 ORM::find和 ORM::find_all方法调用来取得记录。
使用 $user=ORM::factory(‘user’)
->where(‘active’,’=’,TRUE)
->where(‘name’,’=’,’Bob’)
->find();
来抓取用户名为Bob的首条活跃用户。使用 $users=ORM::factory(‘user’)将抓取所有叫Bob的用户。
…
->find_all();
当你使用 ORM::find_all 检索了模型列表,你可以遍历它们作为你的数据库结果来使用:
foreach ($users as $user) {
…
}
Find_all()列表是(一次延迟加载)一个模型对象的数组。如果你使用一个很大的列表,最好使用数据库查询库生成一个数组。
获得对象列表(find_all)
获得对象列表
// 加载所有文章
$articles = Sprig::factory('article')->load(NULL, FALSE);
// 加载开头5篇文章
$articles = Sprig::factory('article')->load(NULL, 5);
// 加载开头5篇文章并按published_date降序排列
$query = DB::select()->order_by('published_date', 'DESC');
$articles = Sprig::factory('article')->load($query, 5);
遍历
count()检查数量,然后使用foreach
...
$articles = Sprig::factory('article')->load($query, 5);
if (count($articles) > 0)
{
foreach($articles as $article)
{
...
}
}
...