hawkbit / database
面向对象的数据库处理
Requires
- php: >=5.5.0
- doctrine/dbal: ~2.5
- doctrine/inflector: ~1.1
Requires (Dev)
- phpunit/phpunit: ~4.8
This package is not auto-updated.
Last update: 2024-09-14 19:47:40 UTC
README
使用 POPO's、工作单元、标识映射和数据映射进行面向对象的数据库处理。
安装
使用 Composer
Hawkbit Database 可在 Packagist 上找到,并可以使用 Composer 安装。可以通过运行以下命令或更新您的 composer.json
文件来实现。
composer require hawkbit/database
composer.json
{ "require": { "hawkbit/database": "~1.0" } }
请确保还将您的 Composer 自动加载文件包含到您的项目中
<?php require __DIR__ . '/vendor/autoload.php';
下载 .zip 文件
此项目也可作为 .zip
文件在 GitHub 上下载。访问 发行页面,选择您想要的版本,然后单击“源代码(zip)”下载按钮。
要求
此版本支持以下版本的 PHP。
- PHP 5.5
- PHP 5.6
- PHP 7.0
- PHP 7.1
- HHVM
使用
连接并开始!
- 注册连接
- 如果您需要使用工作单元和映射器,请注册映射器
- 享受乐趣!
示例
我们还提供了 示例 用于以下文档。
连接
<?php use Hawkbit\Database\ConnectionManager; // setup connection $connection = ConnectionManager::create([ 'url' => 'sqlite:///:memory:', 'memory' => 'true' ]);
共享连接
在大型应用程序中,您需要在多个点访问连接。只需共享您的连接
<?php use Hawkbit\Database\ConnectionManager; ConnectionManager::getInstance()->add($connection);
您可能想节省时间或代码行数,并直接添加连接
<?php use Hawkbit\Database\ConnectionManager; ConnectionManager::getInstance()->add([ 'url' => 'sqlite:///:memory:', 'memory' => 'true' ]);
并在应用程序的另一个点访问连接
<?php use Hawkbit\Database\ConnectionManager; ConnectionManager::getInstance()->get();
多个连接
在某些情况下,您可能需要两个或更多的连接。因此,连接可以有一个名称,默认名称是 default (Hawkbit\Database\ConnectionManager::DEFAULT_CONNECTION
)。
<?php use Hawkbit\Database\ConnectionManager; // add connections ConnectionManager::getInstance()->add([ 'url' => 'sqlite:///:memory:', 'memory' => 'true' ]); ConnectionManager::getInstance()->add([ 'url' => 'mysql://<user>:<password>@<host>/<database>?charset=utf8', ], 'second'); // and access connections $default = ConnectionManager::getInstance()->get(); $second = ConnectionManager::getInstance()->get('second');
前缀
在共享数据库上,使用特定名称前缀表非常有用,例如应用程序缩写。您需要在您的连接上设置前缀。系统将自动前缀所有表名。
添加 PHP 7.1 支持
<?php // setup prefixes $connection->setPrefix('custom_'); $gateway = $connection->createGateway('user'); // connects to custom_user table
如您所见,您(以及映射器)传递表名,内部表名将被前缀。
迁移
使用 SQL 简单设置模式
<?php use Hawkbit\Database\ConnectionManager; // add connections $connection = ConnectionManager::getInstance()->get(); // setup schema $connection->exec('CREATE TABLE post (id int, title VARCHAR(255), content TEXT, date DATETIME DEFAULT CURRENT_DATE )');
使用 phinx 进行高级迁移
此包不提供模式迁移。我们建议使用类似 Phinx 的包进行高级迁移。
网关
网关在数据库和映射器之间进行调解。它能够执行特定表或视图的操作,并提供 CRUD 查询。
从连接创建新的网关
<?php $gateway = $connection->createGateway('post');
创建
创建新条目
<?php // create a new post $gateway->create() ->setValue('title', 'Anything') ->setValue('content', 'Lorem Ipsum') ->execute();
读取(选择)
以数组形式获取条目(参考 \PDO::FETCH_ASSOC
)。条目有以下数组表示形式
<?php $posts = [ 0 => [ 'id' => 1, 'title' => 'Anything', 'content' => 'Lorem Ipsum', ], 1 => [ 'id' => 2, 'title' => 'Anything else', 'content' => 'More text', ] ];
<?php use Doctrine\DBAL\Types\Type; $posts = $gateway ->select() ->where('title = ?') ->setParameter(0, 'Anything', Type::STRING) ->execute() ->fetchAll(); // process entries foreach ($posts as $post){ echo sprintf('<h1>%s</h1><p>%s</p>', $post['title'], $post['content']); }
您还可以使用 doctrines 表达式生成器与 QueryBuilder::createPositionalParameter
和 QueryBuilder::createNamedParameter
结合,进行更复杂的查询!
更新
更新条目
<?php $gateway ->update() ->set('content', 'Cool text instead of Lorem Ipsum, but Lorem Ipsum is cool at all!') ->where('id = 1') ->execute();
删除
删除条目
<?php $gateway ->delete() ->where('id = 1') ->execute();
映射器
数据映射器
数据映射器 将数据映射到实体并从实体提取数据。映射器还了解数据库表配置,并将数据类型转换为两个方向 - PHP 和数据库。它利用 标识映射,确保对象只加载一次。
建议扩展映射器以自定义逻辑来访问关联数据或其他特定数据集。目前不支持数据关联/数据关系!
映射器和实体的组合可能具有Table-Data-Gateway的被动记录风味。
实体
实体表示数据库表或视图的单个条目(行)。它是一组设置器和获取器,没有任何逻辑——被动记录。实体是纯旧PHP对象(POPO)。
准备和加载映射器
将映射器注册到映射器定位器中,以预加载配置并确保访问。当定位器无法找到映射器时,将抛出异常。
<?php use Application\Persistence\Mappers\PostMapper; // register mappers $connection->getMapperLocator()->register(PostMapper::class);
定位已注册的映射器
<?php use Application\Persistence\Entities\Post; $entity = new Post(); $mapper = $connection->loadMapper($entity);
根据实体定位已注册的映射器
<?php use Application\Persistence\Entities\Post; // entity instance is also allowed $mapper = $connection->loadMapper(Post::class); // or create entity from mapper
从映射器创建实体,如果您不想创建新实例的实体
<?php $entity = $mapper->createEntity();
修改数据
映射器能够确定实体状态并保存(创建或更新)数据。映射器正在修改相同的实体实例。对数据库所做的所有更改也将同时存储到实体中。
创建
创建条目
<?php // create entity $entity->setContent('cnt'); $mapper->create($entity);
更新
更新条目
<?php $entity->setContent('FOO'); $mapper->update($entity);
保存
映射器还能够检测新或现有的实体,并选择在数据库中创建或更新相关条目。
<?php $entity->setContent('FOO'); $entity->setTitle('Philosophy of bar, baz & foo'); // create or update $mapper->save($entity);
删除
删除条目
<?php // delete entity $mapper->delete($entity);
获取数据
查找
通过主键或复合键查找条目并返回单个实体结果或false
<?php $post = $mapper->find(['id' => 1]);
自定义选择
以实体列表的形式获取条目。条目具有以下表示
<?php $posts = [ 0 => new Post(), // 'id': 1, 'title': 'Anything', 'content': 'Lorem Ipsum' 1 => new Post(), // 'id': 2, 'title': 'Anything else', 'content': 'More text' ];
选择接受所有有效的可调用的类型来修改查询。
<?php use \Doctrine\DBAL\Query\QueryBuilder; $posts = $mapper->select(function(QueryBuilder $queryBuilder){ // build even more complex queries $queryBuilder->where('id = 1'); }); // process entries /** @var \Application\Persistence\Entities\Post $post */ foreach ($posts as $post){ echo sprintf('<h1>%s</h1><p>%s</p>', $post->getTitle(), $post->getContent()); }
获取单个条目将返回一个实体而不是实体列表
<?php use \Doctrine\DBAL\Query\QueryBuilder; $one = true; $post = $mapper->select(function(QueryBuilder $queryBuilder){ // build even more complex queries $queryBuilder->where('id = 1'); }, ['*'], $one);
事务(工作单元)
为了数据一致性,您想要使用事务。基本上,所有查询都包裹在一个事务中,如果启用了自动提交选项,则自动提交。您也可以创建、更新和删除大量数据,并一次提交它们。
内置的doctrine事务
要使用工作单元,您需要注册一个映射器。在某些情况下,例如原型设计,您可能希望使用网关以快速访问。因此,您应使用内置事务。
<?php try { $connection->beginTransaction(); $gateway->update()->set('content', 'blah')->where('id = 1'); $gateway->update()->set('content', 'blub')->where('id = 2'); $gateway->delete()->where('id in(32,45,16)'); $gateway->create()->setValue('content', 'i am new!')->execute(); $connection->commit(); } catch (\Exception $e) { $connection->rollBack(); // you may want to pass exception to next catch throw $e; }
工作单元 - 与映射器的事务
事务需要注册的映射器才能正确工作。
以任何顺序修改您的数据,工作单元会为您排序创建、更新和删除的执行。如果所有修改都已完成,您需要执行UnitOfWork::commit
。请参考以下工作单元示例。
<?php use Application\Persistence\Entities\Post; $unitOfWork = $connection->createUnitOfWork(); $entity = new Post(); // or create entity from mapper //$entity = $mapper->createEntity(); // create entity $entity->setContent('cnt'); $unitOfWork->create($entity); // commit transaction if(false === $unitOfWork->commit()){ //handle exception $unitOfWork->getException(); // get last processed entity $unitOfWork->getLastProcessed(); } // get all modified entities $unitOfWork->getModified(); // get a list of all entities by state $unitOfWork->getProcessed(); // find entity by primary key or compound key $mapper = $connection->loadMapper($entity); $mapper->find(['id' => 1]); // update entity $entity->setContent('FOO'); $unitOfWork->update($entity); // delete entity $unitOfWork->delete($entity); // commit transaction, again $unitOfWork->commit();
变更日志
有关最近更改的更多信息,请参阅CHANGELOG。
测试
$ composer test
贡献
有关详细信息,请参阅CONTRIBUTING。
安全
如果您发现任何与安全相关的漏洞,请通过电子邮件mjls@web.de而不是使用问题跟踪器。
鸣谢
许可协议
MIT许可(MIT)。有关更多信息,请参阅许可文件。