写点什么

arrayDB,全新而且简单的 PHP ORM 库

  • 2012-10-26
  • 本文字数:3410 字

    阅读完需:约 11 分钟

我见过许多 PHP ORM 库。它们中大多数都要你为想保存在数据库里的每一项写一个类。无缘无故地继承这个、继承那个,而那些内容通常都是重复和反复无常的。

既然条目包含相似数据类型以及相似关系的字段,一个编写良好的类就可适用于所有情况。如果你需要一个库来简化这些事情,这就是我的方法。

arrayDB ORM 库只包含 5 个类。你基本上只使用其中一个,而其余类则在内部使用,仅此而已。缓存及其与数据库之间的同步全是自动的,你无需对其进行跟踪。

要开始使用这个库,你只需简单地定义:

  • 你的数据模型(你需要保存哪几项,他们的字段以及字段间的关系)。
  • 你的 MySQL 连接方式。
  • 你的缓存配置。

定义数据模型

所有的数据模型定义被写成像这样的数组:

复制代码
$model=array(
'user'=>array(
'conf'=>array('len'=>7),
'fields'=>array(
'name'=>array('len'=>50)
),
'has_many'=>array(
'posts'=>array('type'=>'post',
'foreign_name'=>'writer')
),
'many_to_many'=>array(
'liked_posts'=>array('type'=>'post',
'foreign_name'=>'likers'),
),
'self_ref'=>array('friends')
),
'post'=>array(
'conf'=>array('len'=>10),
'fields'=>array(
'text'=>array('len'=>200),
'view_count'=>array('type'=>'numeric', 'len'=>5)
// 默认的字段类型是 text,这里将类型定义成 numeric
)
)
);

这里我们有两张表:用户和帖子。

用户有姓名,有些用户发帖子而有些用户关注帖子。帖子有文本内容,浏览量以及关注者。

用户还有其他许多用户作为好友。

使用这个模型,我们想通过 $user[‘posts’] 获取用户发布的所有帖子,通过 $post[‘writer’] 获取帖子的作者。这是一对多关系。

我们还想通过 $user[‘liked_posts’] 获取用户关注过的帖子,通过 $post[‘likers’] 获取帖子的关注者。这是多对多关系。

最后我们想通过 $user[‘friends’] 获取用户的好友列表。这是自引用关系。

定义 MySQL 连接方式

定义 MySQL 连接方式也写成一个像这样的数组:

复制代码
$db_config=array(
'hostname'=>'localhost', 'database'=>'social',
'username'=>'root', 'password'=>''
);

定义缓存配置

目前,我们有三种缓存类型实现:APC、Memcached 以及普通文本文件。 要使用 APC,这样的配置数组就够了:

复制代码
$cache_config=array('type'=>'apc');

要使用 Memcached,你需要提供一些参数:

复制代码
$cache_config=array('type'=>'memcached', 'host'=>'127.0.0.1',
'port'=>11211, 'timeout'=>1);

要使用普通文本文件,你需要创建一个可读可写的目录并提供其绝对路径:

复制代码
$cache_config=array('type'=>'file', 'path'=>'/tmp/my_project_cache')

还有一个可选参数“prefix”。如果给定,它将用作缓存的键名。

开始使用

现在是时候使用那些我们定义过的数据了。初始化该库,我们只需要这几行代码。

复制代码
DB::init($db_config);
CACHE::init($cache_config);
ADB::init($model);
$adb=ADB::get_instance();

创建表

这项任务只需执行一次。我们告诉库去创建所需的数据库表。它就会负责完成关系等相关的复杂工作。

复制代码
$adb->create_tables();

我们只需在发布的时候执行该方法一次。如果在插入数据之后,调用该方法将导致数据丢失。

使用记录

我们手头拥有这个 $adb 实例。我们将通过它来获取所有数据。

创建记录

我们提供表名和由字段名称及数据组成的键值对数组来创建一条记录。

复制代码
$uid1=$adb->create('user', array('name'=>'John'));
$uid2=$adb->create('user', array('name'=>'Marry'));
$pid1=$adb->create('post', array(
'writer'=>$uid1,
'text'=>'What a wonderful world!'
));
$pid2=$adb->create('post', array(
'writer'=>$uid2,
'text'=>'Life is beautiful!'
));

创建多对多关系

第一个参数是表名。第二个参数是被关联记录的局部名称。第三个参数是记录的 ID,第三个参数是被关联记录的 ID。

复制代码
$adb->relate('user', 'friends', $uid1, $uid2);
$adb->relate('user', 'liked_posts', $uid1, $pid1); // 关注自己的帖子 :)
$adb->relate('user', 'liked_posts', $uid1, $pid2);
$adb->relate('user', 'liked_posts', $uid2, $pid1);

列举数据

我们可在一个简单的循环中列举所有写过帖子的用户以及帖子的关注者:

复制代码
foreach ($adb->id_list('user') as $uid) {
// load user
$user=$adb->load('user', $uid);
echo '<h1>' . $user['name'] . '</h1>' . "\n";
echo '<h2>Posts: </h2>' . "\n";
echo '<ul>' . "\n";
foreach ($user['posts'] as $pid) {
//load post of user
$post=$adb->load('post', $pid);
$likers=array();
foreach ($post['likers'] as $lid) {
// load liker of post
$liker=$adb->load('user', $lid);
$likers[]=$liker['name'];
}
$likers=(count($likers)) ? '<br />' . implode(', ',
$likers) . ' liked.' : '';
echo '<li>' . $post['text'] . ' ' . $likers . '</li>' .
"\n";
}
echo '</ul>' . "\n";
}

更新记录

我们能够像下面这样更新任意一个记录:

复制代码
$user1=$adb->load('user', $uid1);
$user1['name']='Jack';
// 无需调用任何保存方法,保存以及缓存的同步更新全是自动的。

如果我们需要一次更新多个字段,这是另一种方法:

复制代码
$post1=$adb->load('post', $pid1);
$post1->update(array('writer'=>$uid2, 'text'=>'Not a wonderful
world!'));

删除关联

这和创建关联一样:

复制代码
$adb->unrelate('user', 'friends', $uid1, $uid2);
$adb->unrelate('user', 'liked_posts', $uid1, $pid1);

删除记录

我们可以删除记录,同时保存或删除与该记录相关联的数据。

复制代码
$adb->delete('user', $uid1);
// 用户删掉了,帖子成为匿名的了。
$adb->delete('user', $uid1, true);
// 用户以及用户的帖子都删掉了。

查询更多

作为示例,我想获得最受关注的 5 篇帖子。如下是我们所有要做的:

复制代码
foreach ($adb->id_list('post', false, 'likers DESC', 5) as $pid) {
$post=$adb->load('post', $pid);
// 可对帖子做任何操作
}

抑或是我们想要获取用户被关注次数超过 5 次的所有帖子,我们可以执行以下操作:

复制代码
$user=$adb->load('user', $uid1);
foreach ($user->id_list('post', 'view_count>5') as $pid) {
$post=$adb->load('post', $pid);
// 可对帖子做任何操作
}

主要目标

对于单独的帖子页面,我们的代码将会是这么简单:

复制代码
$post=$adb->load('post', $pid1);
$writer=$adb->load('user', $post['writer']);
echo $writer['name'] . ' wrote' . "<br />\n";
echo $post['text'] . "<br />\n";
$post['view_count']++;
// 是的,增大浏览量就是这么简单

这些代码里有任何查询或者缓存逻辑吗?没有,主要目标是保持简单。

市面上有很多著名的替代产品。他们文档完备,支持得也更好。该库不是他们中的一员,它目前还不是一部状态良好的机器。在我看来,这是最简单且容易上手的方法。如果 ORM 库的目的是为了让编码人员不用关心数据库逻辑,这个库是其他新兴库中最自信的一个。jQuery 是最简单的 javascript 框架,也因此成了标准。所以,易于使用的 PHP ORM 库也有这样的机会。

这个库的下载地址:[ arrayDB github ]

欢迎提出意见和建议。

关于作者

Mustafa Dokumaci 是一位来自土耳其伊斯坦布尔的软件工程师。他的专业是环境工程和会计学,但他目前就职于 sporcum.com 和 hipsin.com。Mustafa 拥有六年的 PHP、MySQL、Apache、Nginx、Python、CodeIgniter、Magento 等的使用经验。

查看英文原文 arrayDB, a New and Easy PHP ORM


感谢侯伯薇对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2012-10-26 04:366450
用户头像

发布了 27 篇内容, 共 87278 次阅读, 收获喜欢 4 次。

关注

评论

发布
暂无评论
发现更多内容

java8实战读书笔记:初识Stream、流的基本操作,nginx架构原理

Java 程序员 后端

Java中高级核心知识全面解析——消息队列,mybatis映射原理

Java 程序员 后端

Java使用JDBC开发 之 DBCP连接池,保洁阿姨看完都会了

Java 程序员 后端

Java反射(1),java架构师薪资

Java 程序员 后端

Java反射,mysql开发教程

Java 程序员 后端

Java-进阶:集合框架1,java三个技术平台

Java 程序员 后端

java8实战读书笔记:Lambda表达式语法与函数式编程接口

Java 程序员 后端

JavaWeb之Servlet技术(二),java基础程序设计题

Java 程序员 后端

Java中的几种阻塞队列,kalilinux渗透教程

Java 程序员 后端

Java中的容器,Java开发进大厂面试必备技能

Java 程序员 后端

Java在2018年的形势,MySQL优化原理分析及优化方案总结

Java 程序员 后端

Java垃圾回收机制小结以及优化建议,kafka的工作原理图

Java 程序员 后端

Java基础03 Java的运算符,阿里巴巴java性能调优

Java 程序员 后端

Java中的初始化与清理,kafka参数调优

Java 程序员 后端

java反射map转实体类 实体转map,微服务架构的优缺点

Java 程序员 后端

Java发送邮件,字节跳动上千道精选面试题还不刷起来

Java 程序员 后端

Java基于TCP的网络编程,在阿里工作5年了

Java 程序员 后端

java响应重定向发送post请求,spring+mybatis基础知识

Java 程序员 后端

Java基础复习(DayEleven),应届生面试java开发工程师的题

Java 程序员 后端

Java-进阶:集合框架1(1),java分布式系统面试题

Java 程序员 后端

Java中使用Spring-security(一),java做视频直播

Java 程序员 后端

Java中的几种阻塞队列(1),mybatis返回主键原理

Java 程序员 后端

Java中高级核心知识全面解析——Dubbo,kafka入门到精通文档

Java 程序员 后端

Java中高级核心知识全面解析——消息队列(1),看完这一篇就够了

Java 程序员 后端

java-集合-Map(双列)——迪迦重制版,zookeeper面试

Java 程序员 后端

JavaFx:窗口切换和ListView以及TableView的值绑定,docker面试题

Java 程序员 后端

JavaWeb学习笔记6——事务实例,我的支付宝3面+美团4面+拼多多四面

Java 程序员 后端

java-集合-Map(双列)——迪迦重制版(1),关于线程池的五种实现方式

Java 程序员 后端

JavaWeb Ajax详解,linux操作系统基础教程安俊秀课后答案

Java 程序员 后端

Java中的Type类型详解,javase菜鸟教程

Java 程序员 后端

Java中的程序控制流程,java面试常问知识

Java 程序员 后端

arrayDB,全新而且简单的PHP ORM库_PHP_Mustafa Dokumacı_InfoQ精选文章