efoft/active-records

此包最新版本(1.0.3)没有提供许可证信息。

通过一组简单的命令操作数据库记录的辅助类。

1.0.3 2018-02-13 14:27 UTC

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 方法实现相同的行为。

如果您计划将某些信息作为数组(集合)存储,建议以下步骤

  1. 主数据库表必须使用 InnoDB 引擎,因为它支持外键约束。
  2. 对于将存储集合的每个字段,创建一个具有与字段同名的表,并具有指向主表的外键(请参阅以下示例)。
  3. 此类表 必须 有一个名为 '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'));

在上面的例子中,搜索将在数据库上运行以检查字段nameage,如果它们已经包含要尝试插入的相同数据。

如果验证失败,您可以获取错误信息

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'));

将更新agename字段,对应于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是操作不在先前指定的默认表上运行时的表名。