elvanto / picodb
简约数据库查询构建器
4.4.0
2023-12-04 23:28 UTC
Requires
- php: >=7.0
- ext-pdo: *
Requires (Dev)
- phpunit/phpunit: 6.5.14
README
PicoDb 是一个用于 PHP 的简约数据库查询构建器。
特性
- 易于使用,易于修改,快速且非常轻量级
- 支持的驱动程序:Sqlite, Mssql, Mysql, Postgresql
- 仅需要 PDO
- 使用预处理语句
- 处理模式迁移
- 在 PHP 7+ 上完全单元测试
- 许可证:MIT
要求
- PHP >= 7.0
- PDO 扩展
- Sqlite, Mssql, Mysql 或 Postgresql
作者
Frédéric Guillot
文档
安装
composer require elvanto/picodb
数据库连接
Sqlite
use PicoDb\Database; // Sqlite driver $db = new Database(['driver' => 'sqlite', 'filename' => ':memory:']);
Sqlite 驱动程序默认启用外键。
Microsoft SQL服务器
// Optional attributes: // "schema_table" (the default table name is "schema_version") $db = new Database([ 'driver' => 'mssql', 'hostname' => 'localhost', 'username' => 'root', 'password' => '', 'database' => 'my_db_name', ]);
可选属性
- schema_table
Mysql
$db = new Database([ 'driver' => 'mysql', 'hostname' => 'localhost', 'username' => 'root', 'password' => '', 'database' => 'my_db_name', 'ssl_key' => '/path/to/client-key.pem', 'ssl_cert' => '/path/to/client-cert.pem', 'ssl_ca' => '/path/to/ca-cert.pem', ]);
可选属性
- charset
- schema_table
- port
- ssl_key
- ssl_cert
- ssl_key
- persistent
- timeout
- verify_server_cert
- case
Postgres
$db = new Database([ 'driver' => 'postgres', 'hostname' => 'localhost', 'username' => 'root', 'password' => '', 'database' => 'my_db_name', ]);
可选属性
- port
- schema_table
从环境变量连接
假设您已定义了一个环境变量
export DATABASE_URL=postgres://user:pass@hostname:6212/db
PicoDb 可以自动为您解析此 URL
use PicoDb\UrlParser; use PicoDb\Database; $db = new Database(UrlParser::getInstance()->getSettings());
从 URL 连接
use PicoDb\UrlParser; use PicoDb\Database; $db = new Database(UrlParser::getInstance()->getSettings('postgres://user:pass@hostname:6212/db'));
执行任何 SQL 查询
$db->execute('CREATE TABLE mytable (column1 TEXT)');
- 如果成功,则返回
PDOStatement
- 如果有重复键错误,则返回
false
- 对于其他错误抛出
SQLException
插入
$db->table('mytable')->save(['column1' => 'test']);
或
$db->table('mytable')->insert(['column1' => 'test']);
获取最后插入的 ID
$db->getLastId();
事务
$db->transaction(function ($db) { $db->table('mytable')->save(['column1' => 'foo']); $db->table('mytable')->save(['column1' => 'bar']); });
- 如果回调返回 null,则返回
true
- 否则返回回调返回值
- 如果出错则抛出 SQLException
或
$db->startTransaction(); // Do something... $db->closeTransaction(); // Rollback $db->cancelTransaction();
获取所有数据
$records = $db->table('mytable')->findAll(); foreach ($records as $record) { var_dump($record['column1']); }
更新
$db->table('mytable')->eq('id', 1)->save(['column1' => 'hey']);
或
$db->table('mytable')->eq('id', 1)->update(['column1' => 'hey']);
删除记录
$db->table('mytable')->lt('column1', 10)->remove();
排序
$db->table('mytable')->asc('column1')->findAll();
或
$db->table('mytable')->desc('column1')->findAll();
或
$db->table('mytable')->orderBy('column1', 'ASC')->findAll();
多级排序
$db->table('mytable')->asc('column1')->desc('column2')->findAll();
限制和偏移量
$db->table('mytable')->limit(10)->offset(5)->findAll();
仅获取某些列
$db->table('mytable')->columns('column1', 'column2')->findAll();
仅获取一列
多行
$db->table('mytable')->findAllByColumn('column1');
一行
$db->table('mytable')->findOneColumn('column1');
自定义选择
$db->table('mytable')->select(1)->eq('id', 42)->findOne();
唯一
$db->table('mytable')->distinct('columnA')->findOne();
分组
$db->table('mytable')->groupBy('columnA')->findAll();
计数
$db->table('mytable')->count();
求和
$db->table('mytable')->sum('columnB');
更新时求和列值
将值 42 添加到列 "mycolumn" 的现有值中
$db->table('mytable')->sumColumn('mycolumn', 42)->update();
增加列
在单个查询中增加列值
$db->table('mytable')->eq('another_column', 42)->increment('my_column', 2);
减少列
在单个查询中减少列值
$db->table('mytable')->eq('another_column', 42)->decrement('my_column', 1);
存在
如果记录存在则返回 true,否则返回 false。
$db->table('mytable')->eq('column1', 12)->exists();
左连接
// SELECT * FROM mytable LEFT JOIN my_other_table AS t1 ON t1.id=mytable.foreign_key $db->table('mytable')->left('my_other_table', 't1', 'id', 'mytable', 'foreign_key')->findAll();
或
// SELECT * FROM mytable LEFT JOIN my_other_table ON my_other_table.id=mytable.foreign_key $db->table('mytable')->join('my_other_table', 'id', 'foreign_key')->findAll();
等于条件
$db->table('mytable') ->eq('column1', 'hey') ->findAll();
IN 条件
$db->table('mytable') ->in('column1', ['hey', 'bla']) ->findAll();
带子查询的 IN 条件
$subquery = $db->table('another_table')->columns('column2')->eq('column3', 'value3'); $db->table('mytable') ->columns('column_5') ->inSubquery('column1', $subquery) ->findAll();
LIKE 条件
区分大小写(仅限 Mysql 和 Postgres)
$db->table('mytable') ->like('column1', '%Foo%') ->findAll();
不区分大小写
$db->table('mytable') ->ilike('column1', '%foo%') ->findAll();
小于条件
$db->table('mytable') ->lt('column1', 2) ->findAll();
小于等于条件
$db->table('mytable') ->lte('column1', 2) ->findAll();
大于条件
$db->table('mytable') ->gt('column1', 3) ->findAll();
大于等于条件
$db->table('mytable') ->gte('column1', 3) ->findAll();
IS NULL 条件
$db->table('mytable') ->isNull('column1') ->findAll();
IS NOT NULL 条件
$db->table('mytable') ->notNull('column1') ->findAll();
多个条件
添加条件通过 AND
连接。
$db->table('mytable') ->like('column2', '%mytable') ->gte('column1', 3) ->findAll();
如何创建 OR 条件
$db->table('mytable') ->beginOr() ->like('column2', '%mytable') ->gte('column1', 3) ->closeOr() ->eq('column5', 'titi') ->findAll();
进一步的 AND 条件可以嵌入到 OR 中
$db->table('mytable') ->beginOr() ->like('column2', '%mytable') ->beginAnd() ->gte('column1', 3) ->eq('column5', 'titi') ->closeAnd() ->closeOr() ->findAll();
调试
记录生成的查询
$db->getStatementHandler()->withLogging();
测量每个查询时间
$db->getStatementHandler()->withStopWatch();
获取执行的查询数
echo $db->getStatementHandler()->getNbQueries();
获取日志消息
print_r($db->getLogMessages());
大对象(LOBs)
插入文件
$db->largeObject('my_table')->insertFromFile('blobColumn', '/path/to/file', array('id' => 'something'));
从流中插入
$db->largeObject('my_table')->insertFromStream('blobColumn', $fd, array('id' => 'something'));
以流的形式获取大对象(仅限 Postgres)
$fd = $db->largeObject('my_table')->eq('id', 'something')->findOneColumnAsStream('blobColumn');
以字符串的形式获取大对象
echo $db->largeObject('my_table')->eq('id', 'something')->findOneColumnAsString('blobColumn');
驱动程序
- Postgres
- 列类型:
bytea
- 列类型:
- Sqlite 和 Mysql
- 列类型:
BLOB
- PDO 不支持流功能(返回字符串代替)
- 列类型:
哈希表(键/值存储)
如何将表用作键/值存储
$db->execute( 'CREATE TABLE mytable ( column1 TEXT NOT NULL UNIQUE, column2 TEXT default NULL )' ); $db->table('mytable')->insert(['column1' => 'option1', 'column2' => 'value1']);
添加/替换一些值
$db->hashtable('mytable') ->columnKey('column1') ->columnValue('column2') ->put(['option1' => 'new value', 'option2' => 'value2']));
获取所有值
$result = $db->hashtable('mytable')->columnKey('column1')->columnValue('column2')->get(); print_r($result); Array ( [option2] => value2 [option1] => new value )
或
$result = $db->hashtable('mytable')->getAll('column1', 'column2');
获取特定值
$db->hashtable('mytable') ->columnKey('column1') ->columnValue('column2') ->put(['option3' => 'value3']); $result = $db->hashtable('mytable') ->columnKey('column1') ->columnValue('column2') ->get('option1', 'option3'); print_r($result); Array ( [option1] => new value [option3] => value3 )
模式迁移
定义迁移
- 迁移定义在名为 "Schema" 的命名空间内的简单函数中。
- 将 PDO 实例传递给函数的第一个参数。
- 函数名称末尾包含版本号。
示例
namespace Schema; function version_1($pdo) { $pdo->exec(' CREATE TABLE users ( id INTEGER PRIMARY KEY, name TEXT UNIQUE, email TEXT UNIQUE, password TEXT ) '); } function version_2($pdo) { $pdo->exec(' CREATE TABLE tags ( id INTEGER PRIMARY KEY, name TEXT UNIQUE ) '); }
自动运行模式更新
- 方法
check()
执行所有迁移直到指定版本 - 如果发生错误,则回滚事务
- 在迁移过程中尽可能禁用外键检查
示例
$last_schema_version = 5; $db = new PicoDb\Database(array( 'driver' => 'sqlite', 'filename' => '/tmp/mydb.sqlite' )); if ($db->schema()->check($last_schema_version)) { // Do something... } else { die('Unable to migrate database schema.'); }
使用单例来处理数据库实例
设置新实例
PicoDb\Database::setInstance('myinstance', function() { $db = new PicoDb\Database(array( 'driver' => 'sqlite', 'filename' => DB_FILENAME )); if ($db->schema()->check(DB_VERSION)) { return $db; } else { die('Unable to migrate database schema.'); } });
在任何地方获取此实例
PicoDb\Database::getInstance('myinstance')->table(...)