hwalde/pooq

0.2.0 2020-07-08 23:55 UTC

This package is auto-updated.

Last update: 2024-09-15 05:02:56 UTC


README

POOQ可以从您的数据库生成PHP代码,并通过其流畅的API构建类型安全的SQL查询。

Minimum PHP Version

警告:POOQ目前处于alpha阶段!预期API会发生变化。预期会有bug!请不要在生产环境中使用!

优势

  • 它可以从您的数据库中创建PHP代码。
  • 它可以将查询结果映射到对象。
  • 它允许您编写类型安全的SQL查询。
  • 在处理更复杂的查询时,您不会遇到典型的ORM问题(需要深入了解ORM软件以解决的问题的不正常行为或性能问题)

要求

  • PDO与MySQL(应也能与MariaDB一起工作)

安装

我建议使用Composer进行安装

composer require hwalde/pooq

然后使用Composer的自动加载功能将POOQ包含到您的项目中

require __DIR__ . '/vendor/autoload.php';

示例用法

查询

初始化查询

在查询之前,您需要初始化POOQ一次。

\POOQ\POOQ::initialize('database_name', 'username', 'password', 'hostname', 3306);

或者可以使用现有的PDO

\POOQ\POOQ::initializeUsingExistingPdo($yourPdoObject);

创建选择查询

$t = Thread::as('t'); // Creates an alias name

echo select($t->title(), $t->lastPoster(), $t->postUserName(), $t->replyCount(), $t->threadId())
    ->from($t)
    ->where($t->forumId()->eq(value($forumId)))
    ->order($t->threadId()->desc())
    ->limit(10)
    ->offset(0)
    ->getSql();

输出

SELECT `t`.`title` as `title`, `t`.`lastposter` as `lastposter`, `t`.`postusername` as `postusername`, `t`.`replycount` as `replycount`, `t`.`threadid` as `threadid` 
FROM thread t 
WHERE `t`.`forumid` = 2 
ORDER BY `t`.`threadid` DESC 
LIMIT 10 
OFFSET 0

别名名称是可选的。您始终可以直接使用模型

echo select(Thread::title(), Thread::lastPoster())
    ->from(Thread::class)
    // ...

输出

SELECT `thread`.`title` as `title`, `thread`.`lastposter` as `lastposter`
FROM `thread`
...

将结果映射到对象(所谓记录)

$f = Forum::as('f'); 
$t = Thread::as('t'); 

$resultList = select($f, $t->title()) // Select all fields of Forum and the title field of Thread
    ->from($t)
    ->innerJoin($f)->on($f->forumid()->eq($t->forumid())) // "INNER JOIN forum f ON `f`.`forumid` = `t`.`forumid`"
    ->fetchAll(); // Executes the query and returns ResultList
    
/** @var ThreadRecord[] $threadRecordList */
$threadRecordList = $resultList->into($t); // Maps all Thread fields of ResultList into ThreadRecordList

foreach($threadList as $thread) { // for each row
    echo $thread->getTitle(); // output the title
}

记录可以以ORM方式可选地插入/更新/刷新/删除

// note: this is only supported for tables containing a primary-key

$record->refresh(); // Reload the record from the database
$record->store(); // insert or update the record to the database
$record->delete(); // deletes this record in the database

将记录转换为数组

$array = $recordList->toAssoc();  // Maps entire record-list
$array = $record->toAssoc(); // Maps only a single record

POOQ可以处理具有重叠列名的查询(来自不同表)。例如,如果论坛和线程都有一列"title",那么每个值仍然会映射到正确的对象。

执行更新查询

update(Forum::class) 
    ->set(Forum::title(), 'New title')
    ->set(Forum::description(), 'Lorem ipsum ..')
    ->where(Forum::forumId()->eq(value(123)))
    ->execute();

执行查询

UPDATE forum 
SET `title` = 'New title',
SET `description` = 'Lorem ipsum ..'
WHERE `id` = 123

在更新中使用子查询

update(Thread::class) 
    ->set(Thread::forumId(), 
        select(Forum::forumId())
            ->from(Forum::class)
            ->where(Forum::title()->eq(value('Sample title')))
    )
    ->where(Thread::threadId()->eq(value(123)))
    ->execute();

执行查询

UPDATE forum 
SET `forumId` = (SELECT `forum`.forumId` FROM `forum` WHERE `forum`.`title` = 'Sample title')
WHERE `id` = 123

自定义WHERE子句

并非所有内容都已实现,因此能够编写自定义WHERE子句非常有用

delete(Session::class) 
    ->where(new SimpleCondition(Session::creationDatetime()->toSql() . ' < ' . value($dateTime->format('Y-m-d H:i:s'))->toSql()))
    ->execute();  

代码生成

$config = new \POOQ\CodeGeneration\CodeGeneratorConfig(__DIR__.DIRECTORY_SEPARATOR.'gensrc');
$config->setCopyrightInformation(
<<<END
/**
 * Your custom copyright text!
 */
END
);

// This is optional:
$config->setNameMap(
    [
        // column or tablename => camel-case-name starting lowercase
        'userid' => 'userId',
        'display_order' => 'displayOrder',
        'accessmask' => 'accessMask',
        'product' => 'product',
    ]
);

// This is optional:
$businesslogicFolderPath = __DIR__.'/test/businesslogic';
$config->setModelName2NamespaceMap(new \POOQ\CodeGeneration\ModelName2NamespaceMap(
    [
        // Name of model class => NamespaceObject-object
        'Post' => new \POOQ\CodeGeneration\NamespaceObject(
            'businesslogic\\post',
            $businesslogicFolderPath.'/post'
        ),
        'Forum' => new \POOQ\CodeGeneration\NamespaceObject(
            'businesslogic\\forum',
            $businesslogicFolderPath.'/forum'
        ),
    ]
));
$generator = new \POOQ\CodeGeneration\CodeGenerator($config);
$generator->convertDatabase('database_name', 'username', 'password', 'hostname', 3306);

贡献

请随意改进POOQ并发送您的Pull Requests。不用担心代码风格或其他任何事情。如果需要,我仍然可以适应您的更改。
我对每个贡献都感到高兴。

请随时向我提问!

祝您愉快!