theodorejb / peachy-sql
PHP 的小型、快速数据库抽象层
Requires
- php: >=7.4
Requires (Dev)
- phpunit/phpunit: ^9.5.10
- psalm/plugin-phpunit: ^0.16.1
- ramsey/uuid: ^4.2.3
- vimeo/psalm: ^4.21
README
PeachySQL 是一个快速的数据抽象层,使得执行预编译语句和操作大量数据变得容易。它支持 MySQL 和 SQL Server,并在 PHP 7.4+ 上运行。
通过 Composer 安装
composer require theodorejb/peachy-sql
使用方法
首先使用数据库连接实例化 Mysql
或 SqlServer
类,该连接应该是一个现有的 mysqli 对象 或 SQLSRV 连接资源
$peachySql = new PeachySQL\Mysql($mysqlConn);
或
$peachySql = new PeachySQL\SqlServer($sqlSrvConn);
实例化后,可以通过传递 SQL 字符串和绑定参数数组到 prepare
方法来准备任意语句
$sql = "UPDATE Users SET fname = ? WHERE user_id = ?"; $stmt = $peachySql->prepare($sql, [&$fname, &$id]); $nameUpdates = [ 3 => 'Theodore', 7 => 'Luke', ]; foreach ($nameUpdates as $id => $fname) { $stmt->execute(); } $stmt->close();
大多数情况下,预编译语句只需执行一次。为了简化这个过程,PeachySQL 提供了一个 query
方法,该方法会自动准备、执行并关闭语句,在检索结果后关闭语句
$sql = 'SELECT * FROM Users WHERE fname LIKE ? AND lname LIKE ?'; $result = $peachySql->query($sql, ['theo%', 'b%']); echo json_encode($result->getAll());
prepare
和 query
都返回一个具有以下方法的 Statement
对象
如果使用 MySQL,则 Mysql\Statement
对象还包括一个 getInsertId
方法。
内部,getAll
和 getFirst
是使用 getIterator
实现的。因此,对于给定的语句,它们只能调用一次。
简写方法
PeachySQL 提供了五个简写方法用于选择、插入、更新和删除记录。
注意:为了防止 SQL 注入,PeachySQL 为这些方法生成的查询始终使用绑定参数进行值处理,并且列名会自动转义。
select / selectFrom
selectFrom
方法接受一个包含 SQL SELECT 查询的字符串参数。它返回一个具有三个可链式调用的方法的对象
where
orderBy
offset
此外,该对象还有一个 getSqlParams
方法,用于构建选择查询,还有一个 query
方法,用于执行查询并返回一个 Statement
对象。
// select all columns and rows in a table, ordered by last name and then first name $rows = $peachySql->selectFrom("SELECT * FROM Users") ->orderBy(['lname', 'fname']) ->query()->getAll(); // select from multiple tables with conditions and pagination $rows = $peachySql->selectFrom("SELECT * FROM Users u INNER JOIN Customers c ON c.CustomerID = u.CustomerID") ->where(['c.CustomerName' => 'Amazing Customer']) ->orderBy(['u.fname' => 'desc', 'u.lname' => 'asc']) ->offset(0, 50) // page 1 with 50 rows per page ->query()->getIterator();
select
方法与 selectFrom
相同,但它接受一个 SqlParams
对象而不是字符串,并支持在选择查询中使用绑定参数
use PeachySQL\QueryBuilder\SqlParams; $sql = " WITH UserVisits AS ( SELECT user_id, COUNT(*) AS recent_visits FROM UserHistory WHERE date > ? GROUP BY user_id ) SELECT u.fname, u.lname, uv.recent_visits FROM Users u INNER JOIN UserVisits uv ON uv.user_id = u.user_id"; $date = new DateTime('2 months ago'); $rows = $peachySql->select(new SqlParams($sql, $date->format('Y-m-d'))) ->where(['u.status' => 'verified']) ->query()->getIterator();
WHERE 子句生成
除了向 where
方法传递基本的列 => 值数组外,您还可以通过使用数组作为值来指定更复杂的条件。例如,传递 ['col' => ['lt' => 15, 'gt' => 5]]
将生成条件 WHERE col < 15 AND col > 5
。
支持的运算符完整列表
如果使用 eq
或 ne
运算符传递值列表,它将分别生成 IN(...) 或 NOT IN(...) 条件。传递具有 lk
、nl
、nu
或 nn
运算符的列表将生成对每个值的 AND 条件。不能将 lt
、le
、gt
和 ge
运算符与值列表一起使用。
insertRow
insertRow
方法允许从关联数组插入单行。它返回一个具有 getId
和 getAffected
方法的 InsertResult
对象。
$userData = [ 'fname' => 'Donald', 'lname' => 'Chamberlin' ]; $id = $peachySql->insertRow('Users', $userData)->getId();
insertRows
insertRows
方法使得从数组批量插入多行成为可能。它返回一个具有 getIds
、getAffected
和 getQueryCount
方法的 BulkInsertResult
对象。
$userData = [ [ 'fname' => 'Grace', 'lname' => 'Hopper' ], [ 'fname' => 'Douglas', 'lname' => 'Engelbart' ], [ 'fname' => 'Margaret', 'lname' => 'Hamilton' ] ]; $result = $peachySql->insertRows('Users', $userData); $ids = $result->getIds(); // e.g. [64, 65, 66] $affected = $result->getAffected(); // 3 $queries = $result->getQueryCount(); // 1
可以向insertRows
传递一个可选的第三个参数来覆盖默认的标识符增量值。
$result = $peachySql->insertRows('Users', $userData, 2); $ids = $result->getIds(); // e.g. [64, 66, 68]
注意:SQL Server允许每次插入最多1,000行,并且将单个查询的绑定参数限制在2,099个或更少。MySQL每个查询支持最多65,536个绑定参数。当尝试一次批量插入数百或数千行时,这些限制很容易达到。为了避免这些限制,insertRows
方法会自动将大型查询拆分为批次,以高效地处理任意数量的行(getQueryCount
返回所需的批次数量)。
updateRows和deleteFrom
updateRows
方法接受三个参数:一个表名、一个要更新的列/值的关联数组以及一个WHERE数组来过滤哪些行将被更新。
deleteFrom
方法接受一个表名和一个WHERE数组来过滤要删除的行。
这两个方法都返回受影响的行数。
// update the user with user_id 4 $newData = ['fname' => 'Raymond', 'lname' => 'Boyce']; $peachySql->updateRows('Users', $newData, ['user_id' => 4]); // delete users with IDs 1, 2, and 3 $userTable->deleteFrom('Users', ['user_id' => [1, 2, 3]]);
事务
调用begin
方法来开始一个事务。然后可以按需调用prepare
、execute
、query
和任何简写方法,在提交或回滚事务之前使用commit
或rollback
。
作者
西奥多·布朗
http://theodorejb.me
许可证
MIT