efoft / active-records
通过一组简单的命令操作数据库记录的辅助类。
Requires
- php: >=5.3.0
- efoft/query-builder: 1.0.2
- efoft/query-builder: 1.0.2
This package is not auto-updated.
Last update: 2024-09-29 02:18:38 UTC
README
=====
此包提供了一种简单统一的接口,用于与各种数据库引擎交互。您可以使用相同的方法集独立操作,而无需关心后端数据库是哪种。目前支持
- MongoDB
- MySQL
- SQLite
安装
此包旨在通过 Composer 使用。将以下内容添加到您的 composer.json 中
"require": {
"efoft/active-records" : "dev-master"
}
或者简单地从命令行运行
composer require efoft/active-records
初始化
此包由主类 ActiveRecords 和一些数据库处理器组成。当初始化类实例时,您需要指定其中一个处理器。每种处理器类型都需要一些数据库连接参数。
- MongoDB
- 在本地的 'testdb' 数据库上,无需认证
use ActiveRecords\ActiveRecords;
use ActiveRecords\Handlers\MongoDBHandler;
$ar = new ActiveRecords(new MongoDBHandler('testdb'));
- 在其他主机上,具有认证和非默认端口
$ar = new ActiveRecords(new MongoDBHandler('testdb','username','password','host.example.com', 27018));
- MySQL
- 在本地的 'testdb' 数据库上,具有认证
use ActiveRecords\ActiveRecords;
use ActiveRecords\Handlers\MySQLHandler;
$ar = new ActiveRecords(new MySQLHandler('testdb','username','password'));
- 在其他主机上,具有特定字符集(默认为 UTF-8)
$ar = new ActiveRecords(new MySQLHandler('testdb','username','password','host.example.com',3306,'cp1252'));
- SQLite
use ActiveRecords\ActiveRecords;
use ActiveRecords\Handlers\SQLiteHandler;
$ar = new ActiveRecords(new SQLiteHandler('path/to/dbfile.sqlite'));
! 确保数据库文件路径可写。
数据库准备
与无模式且不需要任何准备的 MongoDB 不同,对于 SQL 引擎,您首先需要在其中创建数据库和表。MongoDB 具有非常方便的功能,可以将序列数组(集合)存储为文档中的字段。
{ "_id" : ObjectId("58c12662a068f30f1f8b4567"), "name" : "John", "age" : NumberLong(28), "tags" : [ "four", "six" ], "imgs" : [ "john.jpg", "all.png" ] }
为了在 SQL 数据库中模拟此功能,此包为每个此类字段使用一个单独的数据库表(子表)。因此,如果数据库调用尝试搜索此类集合,则相关子表将进行左连接。当请求集合修改时,将对子表运行单独的查询以执行此操作。从性能角度来看,这绝对不是针对重负载的最佳解决方案,但对于相对较小的负载是可接受的。
在 MySQL 5.7 中,支持 JSON 类型字段,因此可以在将来使用 JSON 方法实现相同的行为。
如果您计划将某些信息作为数组(集合)存储,建议以下步骤
- 主数据库表必须使用 InnoDB 引擎,因为它支持外键约束。
- 对于将存储集合的每个字段,创建一个具有与字段同名的表,并具有指向主表的外键(请参阅以下示例)。
- 此类表 必须 有一个名为 'relid' 的整数类型列和一个与表本身同名的列,用于存储集合的数据。
以下是在主表 "table1" 和存储与主表记录相关联的数组 "tags" 子表创建的示例
CREATE TABLE `table1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `tags` (
`relid` int(11) NOT NULL,
`tags` text,
KEY `relid` (`relid`),
FOREIGN KEY (`relid`) REFERENCES `table1` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB;
要向现有表添加约束,请使用以下查询
ALTER TABLE tags
ADD CONSTRAINT FOREIGN KEY (`relid`) REFERENCES table1(`id`);
如果由于任何原因无法设置 ON DELETE CASCADE 约束,则设置属性
$ar->setHandlerAttrt('cascade', false);
它将激活在从主表删除记录时在子表上运行的附加例程。所有这些都需要避免子表中的孤儿记录。
用法
表(或 MongoDB 的集合)可以设置一次,用于所有后续操作,也可以在每次单个操作中指定。
$ar->setTable('table1');
$ar->add($data, 'table2');
如果您通过 setTable 设置表名,则它将成为所有未在操作中明确指定表名的案例的默认表。
添加(插入)数据
用法: $ar->add($data, [$tablename]);
$data = array(
'name' => 'Testuser2',
'age' => '36'
);
$ar->add($data);
添加操作返回插入记录的 ID(如果 SQL 数据库中使用了此类字段,则始终返回;在 MongoDB 的情况下总是返回)。
如果添加操作返回NULL,这通常意味着验证失败。
验证
- 在添加/更新操作中使用的$data必须是关联数组。否则验证将失败。
- 您可以为添加操作指定必填字段,以便操作可以继续
$ar->setMandatoryFields(array('name','age'));
- 您可以通过指定要检查的已存在数据的字段来防止创建重复记录
$ar->setUniqueRecordFields(array('name','age'));
在上面的例子中,搜索将在数据库上运行以检查字段name
和age
,如果它们已经包含要尝试插入的相同数据。
如果验证失败,您可以获取错误信息
if ( $inserted = $ar->add($data) )
{
echo "inserted id: $inserted <br>";
}
else
{
if ( $errors = $ar->getError() )
foreach($errors as $k=>$v)
echo "$k: msg: $v['errmsg'], extended info: $v['extinfo']<br>";
}
更新数据
用法:$ar->update($criteria, $data, [$tblname]);
$ar->update(array('id'=>'12'), array('age'=>'36','name'=>'Testuser2'));
将更新age
和name
字段,对应于id
为12的记录。
$data必须是一个数组,可以包括特殊键'$set', '$addToSet', '$push'和'$pull'。它们的含义与MongoDB更新中的含义相同。如果没有指定这些键中的任何一个,则假定'$set'。以下是混合$data更新示例
$ar->update(array('tags'=>'three'),array('age'=>33, '$addToSet'=>array('tags'=>'two','imgs'=>'jack1.jpg')));
因此,如果'two'和'jack1.jpg'还没有在相应的数组'tags'和'imgs'中,它们将被追加到这些数组中,但'age'将设置为33,因为在这种情况下假定'$set'。
删除记录
$ar->delete(array('age'=>'36'));
删除所有年龄字段值为36的记录。
获取数据
有两种用法
- get($criteria, [$projection], [$sort], [$limit], [$tblname]) - 返回包含所有找到的记录数据的二维关联数组
- getOne($criteria, [$projection], [$tblname]) - 返回单个记录作为关联数组
所有参数都是可选的。以下是它们的描述:..$criteria - 以数据库字段名称为键的关联数组。值可以是精确值或正则表达式。对于MongoDB,支持完整的正则表达式语法,并直接传递给MongoDB命令。对于MySQL/SQLite,语法转换为SQL格式,因此只接受有限的语法
/.../ - value of regexp must start and end with slash
/.../i - means to run case-insensitive match
.+ - the combination mean any number of any symbols and converted to % sign for SQL. The combination may be use multiple times in expression.
- $data - 以数据库字段名称为键的关联数组,值是要等于字段
- $sort - 以数据库字段名称为键的关联数组,值可以是(独立于实际数据库类型)
- 'ASC'或1 - 升序排序
- 'DESC'或-1 - 降序排序
- $limit是整数
- $tblname是操作不在先前指定的默认表上运行时的表名。