Sparrow 是一个简单但功能强大的数据库工具包。

v1.1.1 2024-04-19 23:39 UTC

This package is auto-updated.

Last update: 2024-09-20 03:15:28 UTC


README

Sparrow 是一个简单但功能强大的数据库工具包。Sparrow 是一个流畅的 SQL 构建器、数据库抽象层、缓存管理器、查询统计生成器和微型 ORM,全部封装在一个类文件中。

要求

Sparrow 需要 PHP 5.3 或更高版本。

构建 SQL

// Include the library
include '/path/to/Sparrow.php';

// Declare the class instance
$db = new Sparrow;

// Select a table
$db->from('user');

// Build a select query
$db->select();

// Display the SQL
echo $db->sql();

输出

SELECT * FROM user

方法链

Sparrow 允许你将方法链接在一起,因此你可以这样做

echo $db->from('user')->select()->sql();

WHERE 条件

要向查询中添加 WHERE 条件,请使用 where 函数。

echo $db->from('user')
  ->where('id', 123)
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE id=123

你可以多次调用 WHERE 函数来添加多个条件。

echo $db->from('user')
  ->where('id', 123)
  ->where('name', 'bob')
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE id=123 AND name='bob'

你也可以向 WHERE 函数传递一个数组。以下会产生相同的输出。

$where = array('id' => 123, 'name' => 'bob');
echo $db->from('user')
  ->where($where)
  ->select()
  ->sql();

你甚至可以传递一个字符串字面量。

echo $db->from('user')
  ->where('id = 99')
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE id = 99

自定义运算符

WHERE 查询的默认运算符是 =。你可以通过在字段声明后放置运算符来使用不同的运算符。

echo $db->from('user')
  ->where('id >', 123)
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE id>123;

OR 查询

默认情况下,WHERE 条件通过 AND 关键字连接在一起。要使用 OR,只需在字段名之前放置一个 | 分隔符。

echo $db->from('user')
  ->where('id <', 10)
  ->where('|id >', 20)
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE id<10 OR id>20

LIKE 查询

要构建 LIKE 查询,你可以使用特殊的 % 运算符。

echo $db->from('user')
  ->where('name %', '%bob%')
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE name LIKE '%bob%'

要构建 NOT LIKE 查询,在 % 运算符之前添加一个 !

echo $db->from('user')
  ->where('name !%', '%bob%')
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE name NOT LIKE '%bob%'

IN 查询

要在 WHERE 条件中使用 IN 语句,请使用特殊的 @ 运算符并传递一个包含值的数组。

echo $db->from('user')
  ->where('id @', array(10, 20, 30))
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE id IN (10,20,30)

要构建 NOT IN 查询,在 @ 运算符之前添加一个 !

echo $db->from('user')
  ->where('id !@', array(10, 20, 30))
  ->select()
  ->sql();

输出

SELECT * FROM user WHERE id NOT IN (10,20,30)

选择字段

要选择特定字段,将一个数组传递给 select 函数。

echo $db->from('user')
  ->select(array('id','name'))
  ->sql();

输出

SELECT id,name FROM user

限制和偏移

要向查询中添加限制或偏移量,可以使用 limitoffset 函数。

echo $db->from('user')
  ->limit(10)
  ->offset(20)
  ->select()
  ->sql();

输出

SELECT * FROM user LIMIT 10 OFFSET 20

你还可以向 select 函数传递其他参数。

echo $db->from('user')
  ->select('*', 50, 10)
  ->sql();

输出

SELECT * FROM user LIMIT 50 OFFSET 10

Distinct

要向查询中添加 DISTINCT 关键字,请调用 distinct 函数。

echo $db->from('user')
  ->distinct()
  ->select('name')
  ->sql();

输出

SELECT DISTINCT name FROM user

表连接

要添加表连接,请使用 join 函数并传递一个包含要连接的字段的数组。

echo $db->from('user')
  ->join('role', array('role.id' => 'user.id'))
  ->select()
  ->sql();

输出

SELECT * FROM user INNER JOIN role ON role.id=user.id

默认连接类型是 INNER 连接。要构建其他类型的连接,可以使用备用连接函数 leftJoinrightJoinfullJoin

连接数组的工作方式与 WHERE 条件类似,因此你可以使用自定义运算符并添加多个条件。

echo $db->from('user')
  ->join('role', array('role.id' => 'user.id', 'role.id >' => 10))
  ->select()
  ->sql();

输出

SELECT * FROM user INNER JOIN role ON role.id=user.id AND role.id>10

排序

要向查询中添加排序,请使用 sortAscsortDesc 函数。

echo $db->from('user')
  ->sortDesc('id')
  ->select()
  ->sql();

输出

SELECT * FROM user ORDER BY id DESC

你还可以向排序函数传递一个数组。

echo $db->from('user')
  ->sortAsc(array('rank','name'))
  ->select()
  ->sql();

输出

SELECT * FROM user ORDER BY rank ASC, name ASC

分组

要添加一个字段进行分组,请使用 groupBy 函数。

echo $db->from('user')
  ->groupBy('points')
  ->select(array('id','count(*)'))
  ->sql();

输出

SELECT id, count(*) FROM user GROUP BY points

插入查询

要构建插入查询,请将数据数组传递给 insert 函数。

$data = array('id' => 123, 'name' => 'bob');

echo $db->from('user')
  ->insert($data)
  ->sql();

输出

INSERT INTO user (id,name) VALUES (123,'bob')

更新查询

要构建更新查询,请将数据数组传递给 update 函数。

$data = array('name' => 'bob', 'email' => 'bob@aol.com');
$where = array('id' => 123);

echo $db->from('user')
  ->where($where)
  ->update($data)
  ->sql();

输出

UPDATE user SET name='bob',email='bob@aol.com' WHERE id=123

删除查询

要构建删除查询,请使用 delete 函数。

echo $db->from('user')
  ->where('id', 123)
  ->delete()
  ->sql();

输出

DELETE FROM user WHERE id=123

执行查询

Sparrow 还可以执行它构建的查询。你需要调用 setDb() 方法,使用连接字符串、连接信息数组或连接对象。

支持的数据库类型有 mysqlmysqlipgsqlsqlitesqlite3

使用连接字符串

$db->setDb('mysql://admin:hunter2@localhost/mydb');

连接字符串使用以下格式

type://username:password@hostname[:port]/database

对于 sqlite,你需要使用

type://database

使用连接数组

$db->setDb(array(
  'type' => 'mysql',
  'hostname' => 'localhost',
  'database' => 'mydb',
  'username' => 'admin',
  'password' => 'hunter2'
));

可能的数组选项有 typehostnamedatabaseusernamepasswordport

使用连接对象

$mysql = new mysqli('localhost', 'admin', 'hunter2');

$mysql->select_db('mydb');

$db->setDb($mysql);

您还可以使用PDO进行数据库连接。要使用连接字符串或数组方法,请在数据库类型前缀加上pdo

$db->setDb('pdomysql://admin:hunter2@localhost/mydb');

可能的PDO类型有pdomysqlpdopgsqlpdosqlite

您也可以直接传递任何PDO对象。

$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'admin', 'hunter2');

$db->setDb($pdo);

获取记录

要获取多条记录,请使用many函数。

$rows = $db->from('user')
  ->where('id >', 100)
  ->many();

返回的结果是一个关联数组的数组。

array(
  array('id' => 101, 'name' => 'joe'),
  array('id' => 102, 'name' => 'ted');
)

要获取一条记录,请使用one函数。

$row = $db->from('user')
  ->where('id', 123)
  ->one();

返回的结果是一个关联数组。

array('id' => 123, 'name' => 'bob')

要获取列的值,请使用value函数并传入列名。

$username = $db->from('user')
  ->where('id', 123)
  ->value('username');

所有获取函数都会自动执行选择,除非您想指定要返回的字段,否则不需要包含select函数。

$row = $db->from('user')
  ->where('id', 123)
  ->select(array('id', 'name'))
  ->one();

非查询

对于更新、插入和删除等非查询操作,在构建查询后使用execute函数。

$db->from('user')
  ->where('id', 123)
  ->delete()
  ->execute();

执行

DELETE FROM user WHERE id = 123

自定义查询

您还可以通过传递给sql函数来执行原始SQL。

$posts = $db->sql('SELECT * FROM posts')->many();

$user = $db->sql('SELECT * FROM user WHERE id = 123')->one();

$db->sql('UPDATE user SET name = 'bob' WHERE id = 1')->execute();

转义值

Sparrow的SQL构建函数会自动引号和转义值以防止SQL注入。当您自己编写查询时,您可以使用quote函数来手动引号和转义值。

$name = "O'Dell";

printf("SELECT * FROM user WHERE name = %s", $db->quote($name));

输出

SELECT * FROM user WHERE name = 'O\'Dell'

查询属性

执行查询后,将填充几个属性值,您可以直接访问它们。

// Last query executed
$db->last_query;

// Number of rows returned
$db->num_rows;

// Last insert id
$db->insert_id;

// Number of affected rows
$db->affected_rows;

每次执行新查询时,这些值都会重置。

辅助方法

获取表中行数的计数。

$count = $db->from('user')->count();

获取表中的最小值。

$min = $db->from('employee')->min('salary');

获取表中的最大值。

$max = $db->from('employee')->max('salary');

获取表中的平均值。

$avg = $db->from('employee')->avg('salary');

获取表中的总和值。

$avg = $db->from('employee')->sum('salary');

直接访问

您还可以使用getDb函数直接访问数据库对象。

$mysql = $db->getDb();

$mysql->info;

缓存

要启用缓存,您需要使用setCache方法并提供一个连接字符串或连接对象。

使用连接字符串

$db->setCache('memcache://#:11211');

使用缓存对象

$cache = new Memcache;
$cache->addServer('localhost', 11211);

$db->setCache($cache);

然后,您可以将缓存键传递给查询函数,Sparrow将尝试从缓存中获取,然后再执行查询。如果发生缓存未命中,Sparrow将执行查询并将结果使用指定的缓存键存储。

$key = 'all_users';

$users = $db->from('user')->many($key);

缓存类型

支持的缓存有memcachememcachedapcxcachefilememory

要使用memcachememcached,您需要使用以下连接字符串

协议://主机名:端口

要使用apcxcache,只需传入缓存名称

$db->setCache('apc');

要将文件系统用作缓存,请传入目录路径

$db->setCache('/usr/local/cache');

$db->setCache('./cache');

请注意,本地目录必须以./开头。

默认缓存为memory,且仅持续脚本的持续时间。

缓存过期

要仅缓存数据一段时间,您可以传递一个额外的参数,该参数表示以秒为单位的过期时间。

$key = 'top_users';
$expire = 600;

$users = $db->from('user')
  ->sortDesc('score')
  ->limit(100)
  ->many($key, $expire);

在上面的示例中,我们正在获取得分最高的前100名用户的列表,并将它缓存600秒(10分钟)。您可以将过期参数传递给任何接受缓存键参数的查询方法。

直接访问

您可以通过使用getCache函数直接访问缓存对象。

$memcache = $db->getCache();

echo $memcache->getVersion();

您还可以直接操作缓存数据。要缓存值,请使用store函数。

$db->store('id', 123);

要检索缓存值,请使用fetch函数。

$id = $db->fetch('id');

要删除缓存值,请使用clear函数。

$db->clear('id');

要完全清空缓存,请使用flush函数。

$db->flush();

使用对象

麻雀还提供了一些与对象交互的功能。只需定义一个具有公共属性的类来表示数据库字段,以及静态变量来描述数据库关系。

class User {
  // Class properties
  public $id;
  public $name;
  public $email;

  // Class configuration
  static $table = 'user';
  static $id_field = 'id';
  static $name_field = 'name';
}

类配置

  • 属性table表示数据库表。此属性为必填项。
  • 属性id_field表示表中的自增标识字段。此属性对于保存和删除记录是必需的。
  • 属性name_field用于按名称查找记录。此属性为可选。

加载对象

要定义对象,请使用using函数并传入类名。

$db->using('User');

设置对象后,您可以使用find方法填充对象。如果您传入一个整数,麻雀将使用ID字段进行搜索。

$user = $db->find(123);

这将执行

SELECT * FROM user WHERE id = 123

如果您传入一个字符串,麻雀将使用名称字段进行搜索。

$user = $db->find('Bob');

这将执行

SELECT * FROM user WHERE name = 'Bob';

如果您传入一个数组,麻雀将使用数组中指定的字段。

$user = $db->find(
  array('email' => 'bob@aol.com')
);

这将执行

SELECT * FROM user WHERE email = 'bob@aol.com'

如果find方法检索到多个记录,它将返回一个对象数组而不是单个对象。

保存对象

要保存对象,只需填充对象属性并使用save函数。

$user = new User();
$user->name = 'Bob';
$user->email = 'bob@aol.com';

$db->save($user);

这将执行

INSERT INTO user (name, email) VALUES ('Bob', 'bob@aol.com')

要更新对象,请使用包含已填充id_field属性的save函数。

$user = new User();
$user->id = 123;
$user->name = 'Bob';
$user->email = 'bob@aol.com';

$db->save($user);

这将执行

UPDATE user SET name = 'Bob', email = 'bob@aol.com' WHERE id = 123

要更新现有记录,只需从数据库中获取一个对象,更新其属性,然后保存。

// Fetch an object from the database
$user = $db->find(123);

// Update the object
$user->name = 'Fred';

// Update the database
$db->save($user);

默认情况下,对象的所有属性都将包含在更新中。要指定仅特定字段,请将额外的字段数组传递给save函数。

$db->save($user, array('email'));

这将执行

UPDATE user SET email = 'bob@aol.com' WHERE id = 123

删除对象

要删除对象,请使用remove函数。

$user = $db->find(123);

$db->remove($user);

高级查找

您可以使用SQL构建器函数进一步定义加载对象的准则。

$db->using('User')
  ->where('id >', 10)
  ->sortAsc('name')
  ->find();

这将执行

SELECT * FROM user WHERE id > 10 ORDER BY name ASC

您还可以传入原始SQL来加载对象。

$db->using('User')
  ->sql('SELECT * FROM user WHERE id > 10')
  ->find();

统计信息

麻雀内置查询统计跟踪。要启用它,只需设置stats_enabled属性。

$db->stats_enabled = true;

运行查询后,获取统计数组

$stats = $db->getStats();

统计数组包含所有查询的总时间以及所有已执行的查询的数组及其各自的查询时间。

array(6) {
  ["queries"]=>
  array(2) {
    [0]=>
    array(4) {
      ["query"]=>
        string(38) "SELECT * FROM user WHERE uid=1"
      ["time"]=>
        float(0.00016617774963379)
      ["rows"]=>
        int(1)
      ["changes"]=>
        int(0)
    }
    [1]=>
    array(4) {
      ["query"]=>
        string(39) "SELECT * FROM user WHERE uid=10"
      ["time"]=>
        float(0.00026392936706543)
      ["rows"]=>
        int(0)
      ["changes"]=>
        int(0)
    }
  }
  ["total_time"]=>
    float(0.00043010711669922)
  ["num_queries"]=>
    int(2)
  ["num_rows"]=>
    int(2)
  ["num_changes"]=>
    int(0)
  ["avg_query_time"]=>
    float(0.00021505355834961)
}

调试

当麻雀在执行查询时遇到错误,它将抛出一个包含数据库错误信息的异常。如果您想显示生成的SQL以及错误信息,请设置show_sql属性。

$db->show_sql = true;

许可证

麻雀在MIT许可证下发布。