ezswoole / dbobject
easyswoole mysqli dbObject
Requires
- easyswoole/mysqli: ^1.0
- easyswoole/spl: ^1.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-28 02:40:55 UTC
README
https://github.com/easy-swoole/mysqli
由于开发频率较高,为了随时调试使用、composer不重名包,所以单独发布一份的供快速迭代
数据库-Mysqli
EasySwoole 提供了一个基于 https://github.com/ThingEngineer/PHP-MySQLi-Database-Class 的协程安全 ORM。
EasySwoole/mysqli:https://github.com/easy-swoole/mysqli
安装
composer require easyswoole/mysqli
基本用法
use EasySwoole\Mysqli\Config;
$conf = new Config([
'host'=>'',
'user'=>'',
'password'=>'',
'database'=>'',
'port'=>''
]);
$db = new Mysqli($conf);
$data = $db->get('test');
Mysqli 连接池
声明 MysqlPool
use EasySwoole\Component\Pool\AbstractPool;
use EasySwoole\EasySwoole\Config;
class MysqlPool extends AbstractPool
{
protected function createObject()
{
// TODO: Implement createObject() method.
$dbConf = new Config([
//config array
]);
return new MysqlDbObject($dbConf);
}
}
声明 MysqlDbObject
use EasySwoole\Component\Pool\PoolObjectInterface;
use EasySwoole\Mysqli\Mysqli;
class MysqlDbObject extends Mysqli implements PoolObjectInterface
{
/*
call when MysqlDbObject is bean recycle
*/
function gc()
{
/*
call this is in order to prevent when exception occur but you did not
catch the eror an forget to rollback you operator
*/
$this->rollback();
$this->commit();
$this->resetDbStatus();
$this->getMysqlClient()->close();
}
/*
call when MysqlDbObject is return to pool
*/
function objectRestore()
{
/*
call this is in order to prevent when exception occur but you did not
catch the eror an forget to rollback you operator
*/
$this->rollback();
$this->commit();
$this->resetDbStatus();
}
/*
call when MysqlDbObject is pop from pool
return true mean this object is active
*/
function beforeUse(): bool
{
// TODO: Implement beforeUse() method.
return true;
}
}
连接池实现在 easyswoole/component
用法列表
插入
$data = Array ("login" => "admin",
"firstName" => "John",
"lastName" => 'Doe'
);
$id = $db->insert ('users', $data);
if($id)
echo 'user was created. Id=' . $id;
//Insert with functions use
$data = Array (
'login' => 'admin',
'active' => true,
'firstName' => 'John',
'lastName' => 'Doe',
'password' => $db->func('SHA1(?)',Array ("secretpassword+salt")),
// password = SHA1('secretpassword+salt')
'createdAt' => $db->now(),
// createdAt = NOW()
'expires' => $db->now('+1Y')
// expires = NOW() + interval 1 year
// Supported intervals [s]econd, [m]inute, [h]hour, [d]day, [M]onth, [Y]ear
);
$id = $db->insert ('users', $data);
if ($id)
echo 'user was created. Id=' . $id;
else
echo 'insert failed: ' . $db->getLastError();
//Insert with on duplicate key update
$data = Array ("login" => "admin",
"firstName" => "John",
"lastName" => 'Doe',
"createdAt" => $db->now(),
"updatedAt" => $db->now(),
);
$updateColumns = Array ("updatedAt");
$lastInsertId = "id";
$db->onDuplicate($updateColumns, $lastInsertId);
$id = $db->insert ('users', $data);
更新查询
$data = Array (
'firstName' => 'Bobby',
'lastName' => 'Tables',
'editCount' => $db->inc(2),
// editCount = editCount + 2;
'active' => $db->not()
// active = !active;
);
$db->where ('id', 1);
if ($db->update ('users', $data))
echo $db->count . ' records were updated';
else
echo 'update failed: ' . $db->getLastError();
update() 也支持 limit 参数
$db->update ('users', $data, 10);
// Gives: UPDATE users SET ... LIMIT 10
选择查询
$users = $db->get('users'); //contains an Array of all users
$users = $db->get('users', 10); //contains an Array 10 users
或选择自定义列集。函数也可以使用
$cols = Array ("id", "name", "email");
$users = $db->get ("users", null, $cols);
if ($db->count > 0)
foreach ($users as $user) {
print_r ($user);
}
或选择一行
$db->where ("id", 1);
$user = $db->getOne ("users");
echo $user['id'];
$stats = $db->getOne ("users", "sum(id), count(*) as cnt");
echo "total ".$stats['cnt']. "users found";
或选择一个列值或函数结果
$count = $db->getValue ("users", "count(*)");
echo "{$count} users found";
从多行中选择一个列值或函数结果
$logins = $db->getValue ("users", "login", null);
// select login from users
$logins = $db->getValue ("users", "login", 5);
// select login from users limit 5
foreach ($logins as $login)
echo $login;
执行原始 SQL 查询
$users = $db->rawQuery('SELECT * from users where id >= 100');
foreach ($users as $user) {
print_r ($user);
}
Where / Having 方法
where()
、orWhere()
、having()
和 orHaving()
方法允许您指定查询的 where 和 having 条件。where() 所支持的任何条件都由 having() 支持。
警告:为了使用列与列的比较,仅应使用原始 where 条件作为列名,或者不能将列名或函数作为绑定变量传递。
常规 == 操作符与变量
$db->where ('id', 1); $db->where ('login', 'admin'); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE id=1 AND login='admin';
$db->where ('id', 1); $db->having ('login', 'admin'); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE id=1 HAVING login='admin';
常规 == 操作符与列与列比较
// WRONG $db->where ('lastLogin', 'createdAt'); // CORRECT $db->where ('lastLogin = createdAt'); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE lastLogin = createdAt;
$db->where ('id', 50, ">="); // or $db->where ('id', Array ('>=' => 50)); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE id >= 50;
BETWEEN / NOT BETWEEN
$db->where('id', Array (4, 20), 'BETWEEN'); // or $db->where ('id', Array ('BETWEEN' => Array(4, 20))); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id BETWEEN 4 AND 20
IN / NOT IN
$db->where('id', Array(1, 5, 27, -1, 'd'), 'IN'); // or $db->where('id', Array( 'IN' => Array(1, 5, 27, -1, 'd') ) ); $results = $db->get('users'); // Gives: SELECT * FROM users WHERE id IN (1, 5, 27, -1, 'd');
OR CASE
$db->where ('firstName', 'John'); $db->orWhere ('firstName', 'Peter'); $results = $db->get ('users'); // Gives: SELECT * FROM users WHERE firstName='John' OR firstName='peter'
NULL 比较
$db->where ("lastName", NULL, 'IS NOT'); $results = $db->get("users"); // Gives: SELECT * FROM users where lastName IS NOT NULL
LIKE 比较
$db->where ("fullName", 'John%', 'like'); $results = $db->get("users"); // Gives: SELECT * FROM users where fullName like 'John%'
您还可以使用原始 where 条件
$db->where ("id != companyId"); $db->where ("DATE(createdAt) = DATE(lastLogin)"); $results = $db->get("users");
或带有变量的原始条件
$db->where ("(id = ? or id = ?)", Array(6,2)); $db->where ("login","mike") $res = $db->get ("users"); // Gives: SELECT * FROM users WHERE (id = 6 or id = 2) and login='mike';
查找匹配的行总数。简单的分页示例
$offset = 10; $count = 15; $users = $db->withTotalCount()->get('users', Array ($offset, $count)); echo "Showing {$count} from {$db->totalCount}";
查询关键词
可以将 LOW PRIORITY | DELAYED | HIGH PRIORITY | IGNORE 以及其余的 mysql 关键词添加到 INSERT ()、REPLACE ()、GET ()、UPDATE ()、DELETE () 方法中,或将 FOR UPDATE | LOCK IN SHARE MODE 添加到 SELECT () 中
$db->setQueryOption ('LOW_PRIORITY')->insert ($table, $param); // GIVES: INSERT LOW_PRIORITY INTO table ...
$db->setQueryOption ('FOR UPDATE')->get ('users'); // GIVES: SELECT * FROM USERS FOR UPDATE;
您还可以使用关键词数组
$db->setQueryOption (Array('LOW_PRIORITY', 'IGNORE'))->insert ($table,$param); // GIVES: INSERT LOW_PRIORITY IGNORE INTO table ...
同样,关键词也可以用在 SELECT 查询中
$db->setQueryOption ('SQL_NO_CACHE'); $db->get("users"); // GIVES: SELECT SQL_NO_CACHE * FROM USERS;
可选地,您可以使用方法链多次调用 where 而不必每次都引用您的对象
$results = $db ->where('id', 1) ->where('login', 'admin') ->get('users');
删除查询
$db->where('id', 1); if($db->delete('users')) echo 'successfully deleted';
排序方法
$db->orderBy("id","asc"); $db->orderBy("login","Desc"); $db->orderBy("RAND ()"); $results = $db->get('users'); // Gives: SELECT * FROM users ORDER BY id ASC,login DESC, RAND ();
排序值示例
$db->orderBy('userGroup', 'ASC', array('superuser', 'admin', 'users')); $db->get('users'); // Gives: SELECT * FROM users ORDER BY FIELD (userGroup, 'superuser', 'admin', 'users') ASC;
如果您正在使用 setPrefix () 功能并需要在 orderBy () 方法中使用表名,请确保使用 `` 将表名转义。
$db->setPrefix ("t_"); $db->orderBy ("users.id","asc"); $results = $db->get ('users'); // WRONG: That will give: SELECT * FROM t_users ORDER BY users.id ASC; $db->setPrefix ("t_"); $db->orderBy ("`users`.id", "asc"); $results = $db->get ('users'); // CORRECT: That will give: SELECT * FROM t_users ORDER BY t_users.id ASC;
分组方法
$db->groupBy ("name"); $results = $db->get ('users'); // Gives: SELECT * FROM users GROUP BY name;
通过 tenantID 使用 LEFT JOIN 将 products 表与 users 表连接
JOIN 方法
$db->join("users u", "p.tenantID=u.tenantID", "LEFT"); $db->where("u.id", 6); $products = $db->get ("products p", null, "u.name, p.productName"); print_r ($products);
JOIN 条件
向 JOIN 语句添加 AND 条件
$db->join("users u", "p.tenantID=u.tenantID", "LEFT"); $db->joinWhere("users u", "u.tenantID", 5); $products = $db->get ("products p", null, "u.name, p.productName"); print_r ($products); // Gives: SELECT u.login, p.productName FROM products p LEFT JOIN users u ON (p.tenantID=u.tenantID AND u.tenantID = 5)
向 JOIN 语句添加 OR 条件
$db->join("users u", "p.tenantID=u.tenantID", "LEFT"); $db->joinOrWhere("users u", "u.tenantID", 5); $products = $db->get ("products p", null, "u.name, p.productName"); print_r ($products); // Gives: SELECT u.login, p.productName FROM products p LEFT JOIN users u ON (p.tenantID=u.tenantID OR u.tenantID = 5)
属性共享
您还可以复制属性
$db->where ("agentId", 10); $db->where ("active", true); $customers = $db->copy (); $res = $customers->get ("customers", Array (10, 10)); // SELECT * FROM customers where agentId = 10 and active = 1 limit 10, 10 $cnt = $db->getValue ("customers", "count(id)"); echo "total records found: " . $cnt; // SELECT count(id) FROM users where agentId = 10 and active = 1
子查询
子查询初始化
子查询初始化不带别名以用于插入/更新/where。例如:(select * from users)
$sq = $db->subQuery(); $sq->get ("users");
指定别名的子查询以用于 JOIN。例如:(select * from users) sq
$sq = $db->subQuery("sq"); $sq->get ("users");
选择查询中的子查询
$ids = $db->subQuery (); $ids->where ("qty", 2, ">"); $ids->get ("products", null, "userId"); $db->where ("id", $ids, 'in'); $res = $db->get ("users"); // Gives SELECT * FROM users WHERE id IN (SELECT userId FROM products WHERE qty > 2)
插入中的子查询
$userIdQ = $db->subQuery (); $userIdQ->where ("id", 6); $userIdQ->getOne ("users", "name"), $data = Array ( "productName" => "test product", "userId" => $userIdQ, "lastUpdated" => $db->now() ); $id = $db->insert ("products", $data); // Gives INSERT INTO PRODUCTS (productName, userId, lastUpdated) values ("test product", (SELECT name FROM users WHERE id = 6), NOW());
JOIN 中的子查询
$usersQ = $db->subQuery ("u"); $usersQ->where ("active", 1); $usersQ->get ("users"); $db->join($usersQ, "p.userId=u.id", "LEFT"); $products = $db->get ("products p", null, "u.login, p.productName"); print_r ($products); // SELECT u.login, p.productName FROM products p LEFT JOIN (SELECT * FROM t_users WHERE active = 1) u on p.userId=u.id;
EXISTS / NOT EXISTS 条件
$sub = $db->subQuery(); $sub->where("company", 'testCompany'); $sub->get ("users", null, 'userId'); $db->where (null, $sub, 'exists'); $products = $db->get ("products"); // Gives SELECT * FROM products WHERE EXISTS (select userId from users where company='testCompany')
has 方法
一个方便的函数,如果至少有一个元素满足在调用此方法之前的 "where" 方法指定的条件,则返回 TRUE。
$db->where("user", $user); $db->where("password", md5($password)); if($db->has("users")) { return "You are logged"; } else { return "Wrong user/password"; }
辅助方法
从数据库断开连接
$db->disconnect();
如果 mysql 连接失败,重新连接
if (!$db->ping()) $db->connect()
获取最后执行的SQL查询:请注意,此函数仅用于调试目的,因为其执行很可能会因缺少字符变量周围的引号而失败。
$db->get('users'); echo "Last executed query was ". $db->getLastQuery();
检查表是否存在
if ($db->tableExists ('users')) echo "hooray";
mysqli_real_escape_string()包装器
$escaped = $db->escape ("' and 1=1");
事务辅助函数
请注意,事务是在InnoDB表上工作的。如果插入失败,则回滚事务
$db->startTransaction(); ... if (!$db->insert ('myTable', $insertData)) { //Error while saving, cancel new record $db->rollback(); } else { //OK $db->commit(); }
错误辅助函数
在执行查询后,您可以选择检查是否发生错误。您可以获取最后一个执行查询的MySQL错误字符串或错误代码。
$db->where('login', 'admin')->update('users', ['firstName' => 'Jack']); if ($db->getLastErrno() === 0) echo 'Update succesfull'; else echo 'Update failed. Error: '. $db->getLastError();
查询执行时间基准测试
要跟踪查询执行时间,应调用setTrace()函数。
$db->setTrace (true); // As a second parameter it is possible to define prefix of the path which should be striped from filename // $db->setTrace (true, $_SERVER['SERVER_ROOT']); $db->get("users"); $db->get("test"); print_r ($db->trace);
[0] => Array
(
[0] => SELECT * FROM t_users ORDER BY `id` ASC
[1] => 0.0010669231414795
[2] => MysqliDb->get() >> file "/avb/work/PHP-MySQLi-Database-Class/tests.php" line #151
)
[1] => Array
(
[0] => SELECT * FROM t_test
[1] => 0.00069189071655273
[2] => MysqliDb->get() >> file "/avb/work/PHP-MySQLi-Database-Class/tests.php" line #152
)
表锁定
要锁定表,您可以使用lock
方法和setLockMethod
。以下示例将锁定users
表以进行写
访问。
$db->setLockMethod("WRITE")->lock("users");
再次调用->lock()
将删除第一个锁定。您还可以使用以下方法解锁之前锁定的表。
$db->unlock();
要锁定多个表,您可以使用数组。例如
$db->setLockMethod("READ")->lock(array("users", "log"));
这将锁定users
和log
表仅进行读取
访问。确保在之后使用unlock(),否则您的表将保持锁定状态!