当前位置: 首页 > 文档资料 > FuelPHP 中文文档 >

Database 用法 - 类別

优质
小牛编辑
120浏览
2023-12-01

Database 用法

正常的资料库是透过 DB 类别 去互动, 下面的範例会让你感觉到在 Fuel 里如何使用资料库。

Database 用法分为几段:

执行查询

首先我们使用 DB::query 预处理一个查询。

// 回传一个新的 Database_Query
$query = DB::query('SELECT * FROM `users`');

现在我们可以执行查询:

$query = DB::query('SELECT * FROM `users`');

// 回传一个新的 Database_MySQLi_Result
$query->execute();

// 或执行在不同的资料库群组
$query->execute('another_group');
// 或
$query->execute(Database_Connection::instance('another_group'));

// 而且我们可以像这样串联:
$result = DB::query('SELECT * FROM `users`')->execute();

选择资料

首先让我们使用 DB::query 选择资料, 由于我们要取出此查询结果, 我们需要让它知道我们要运行什幺样的查询。


$result = DB::query('SELECT * FROM `users`', DB::SELECT)->execute();

我们也可以使用 DB::select 选择资料

// 将执行 SELECT `id`, `name` FROM `users`
$result = DB::select('id','name')->from('users')->execute();

或使用 DB::select_array 可以让你动态建立你的列名称阵列。

// 将执行 SELECT `id`, `name` FROM `users`
$colums = array('id', 'name');
$result = DB::select_array($columns)->from('users')->execute();

如果你想要别名行,使用阵列代替字串。

// 将执行 SELECT `name` as `the_name` FROM `users`;
$result = DB::select(array('name','the_name'))->from('users')->execute();

要选择相异的值设定 distinct 为 true

// SELECT DISTINCT `name` FROM `users`
$users = DB::select('name')->from('users')->distinct(true)->execute();

print_r($users->as_array());
/*
Array
(
    [0] => Array
        (
            [name] => Dirk
        )

    [1] => Array
        (
            [name] => John
        )

)
*/

结果

执行 Select 查询将产生一个结果物件,包含请求的资料库纪录。 预设情况下,结果被取出做为关联阵列, 这里有一个範例如何牵动此行为。

// 将取出结果做为一个关联阵列。
$result = DB::select('id','name')->from('users')->as_assoc()->execute();

// 将取出结果做为一个物件。
$result = DB::select('id','name')->from('users')->as_object()->execute();

// 将取出结果做为一个 Model_Users 物件。
$result = DB::select()->from('users')->as_object('Model_Users')->execute();

// 将取出结果做为一个 Model_Users 物件(一个来自 Users 模组的模型)。
$result = DB::select()->from('users')->as_object('\\Users\\Model_Users')->execute();

当你传递一个类别名称到 as_object(),确认你引入任何有需要的命名空间。 如果指定类别不存在,as_object() 将被忽略,并且将回传一个索引阵列。

想知道你取出多少条纪录?极度简单!


$result = DB::select('*')->from('users')->execute();
// 只要计算结果,它回传一个整数。
$num_rows = count($result);

要存取这些结果,你可以直接透过结果物件做迴圈,或取得结果阵列。

$result = DB::select()->from('users')->execute();
foreach($result as $item)
{
	// 用 $item 做点什幺
}

$result_array = $result->as_array();
foreach($result_array as $item)
{
	// 用 $item 做点什幺
}

(选择性)我们对从 as_array 回传的阵列指定键与值

$result = DB::select()->from('users')->execute();
$on_key = $result->as_array('id');
foreach($on_key as $id => $item)
{
	// $id 将包含纪录的 id
	// 用 $item 或它的 $id 做点什幺
}

$key_value = $result->as_array('id', 'email');
foreach($key_value as $id => $email)
{
	// 现在 $email 将成为 email 栏位。
	// 所以你可以用 $id 或 $email 做点什幺
}

过滤

Where 语句

为了在我们的查询设定条件,我们可以设定 WHERE 条件。 这些範例也适用于更新和删除。

// 将执行 SELECT * FROM `users` WHERE `id` = 1
$result = DB::select()->from('users')->where('id', 1)->execute();

要影响运算子,像这样提供它:

// 将执行 SELECT * FROM `users` WHERE `id` = 1
$result = DB::select()->from('users')->where('id', '=', 1)->execute();

// 将执行 SELECT * FROM `users` WHERE `id` IN (1, 2, 3)
$id_array = array(1,2,3);
$result = DB::select()->from('users')->where('id', 'in', $id_array)->execute();

// 将执行 SELECT * FROM `users` WHERE `id` BETWEEN 1 AND 2
$result = DB::select()->from('users')->where('id', 'between', array(1, 2))->execute();

// 将执行 SELECT * FROM `users` WHERE `id` != 1
$result = DB::select()->from('users')->where('id', '!=', 1)->execute();

// 将执行 SELECT * FROM `users` WHERE `name` LIKE "john%"
$who = "john%";
$result = DB::select()->from('users')->where('name', 'like', $who)->execute();

成群的 where 语句也被支援:

// SELECT * FROM `users` WHERE (`name` = 'John' AND `email` = 'john@example.com')
// OR (`name` = 'mike' OR `name` = 'dirk')
$result = DB::select()->from('users')->where_open()
	->where('name', 'John')
	->and_where('email', 'john@example.com')
->where_close()
->or_where_open()
	->where('name', 'mike')
	->or_where('name', 'dirk')
->or_where_close()->execute();

BETWEENIN 也透过 where 方法运作:

// SELECT * FROM `users` WHERE `id` BETWEEN 1 AND 10
$users = DB::select()->from('users')->where('id', 'between', array(1, 10))->execute();

// SELECT * FROM `users` WHERE `name` IN ('john', 'simon', 'dirk')
$users = DB::select()->from('users')->where('name', 'in', array('john', 'simon', 'dirk'))->execute();

Order by 语句

我们使用 order_by function 函式排序资料。

// SELECT * FROM `users` ORDER BY `name` ASC
DB::select()->from('users')->order_by('name','asc');

// SELECT * FROM `users` ORDER BY `name` ASC, `surname` DESC
DB::select()->from('users')->order_by('name','asc')->order_by('surname', 'desc');

// 你可以藉由略去第二个参数来省略方向。
// SELECT * FROM `users` ORDER BY `name`
DB::select()->from('users')->order_by('name');

Limit 和 offset

我们使用 limit 和 offset 函式来限制取回的笔数。请注意,offset 函式只在选择资料时可用。

// SELECT * FROM `users` LIMIT 1
DB::select()->from('users')->limit(1);

// SELECT * FROM `users` LIMIT 10 OFFSET 5
DB::select()->from('users')->limit(10)->offset(5);

// SELECT * FROM `users` ORDER BY `id` ASC LIMIT 10
DB::select()->from('users')->order_by('id','asc')->limit(10);

更新

我们使用 DB::update 来更新资料, 如果成功执行一个 Update 查询将回传一个整数, 代表受影响的笔数。

要更新单一行。

// 将执行 UPDATE `users` SET `name` = "John Random" WHERE `id` = "2";
$result = DB::update('users')
	->value("name", "John Random")
	->where('id', '=', '2')
	->execute();

要更新多个行。

// 将执行 UPDATE `users`
// SET `group` = "Peter Griffon", `email` = "peter@thehindenpeter.com"
// WHERE `id` = "16";
$result = DB::update('users')
	->set(array(
		'name'  => "Peter Griffon",
		'email' => "peter@thehindenpeter.com"
	))
	->where('id', '=', '16')
	->execute();

新增

我们使用 DB::insert 新增资料, 如果成功执行一个 Insert 查询将回传一个阵列, 包含新增 ID 和建立列的列表。

// 将执行 INSERT INTO `users`(`name`,`email`,`password`)
// VALUES ("John Random", "john@example.com", "s0_s3cr3t")
list($insert_id, $rows_affected) = DB::insert('users')->set(array(
	'name' => 'John Random',
	'email' => 'john@example.com',
	'password' => 's0_s3cr3t',
))->execute();

你也可以分别设定行和值

// 将执行 INSERT INTO `users`(`name`,`email`,`password`)
// VALUES ("John Random", "john@example.com", "s0_s3cr3t")
list($insert_id, $rows_affected) = DB::insert('users')->columns(array(
	'name', 'email', 'password'
))->values(array(
	'John Random', 'john@example.com', 's0_s3cr3t'
))->execute();

删除

要删除资料,使用 DB::delete。 当执行时将回传受影响的笔数。

// 清空整个 users 表
$result = DB::delete('users')->execute(); // (int) 20

// 执行 DELETE FROM `users` WHERE `email` LIKE "%@example.com"
$result = DB::delete('users')->where('email', 'like', '%@example.com')->execute(); // (int) 7

组合

当选择资料,你也可以组合其他表到结果。

// 将执行 SELECT * FROM `users` LEFT JOIN `roles` ON `roles`.`id` = `users`.`role_id`
$result = DB::select()->from('users')->join('roles','LEFT')->on('roles.id', '=', 'users.role_id');

// 将执行 SELECT * FROM `users` RIGHT OUTER JOIN `roles` ON `roles`.`id` = `users`.`role_id`
$result = DB::select()->from('users')->join('roles','right outer')->on('roles.id', '=', 'users.role_id');

// 在一个字面值 1 组合,而不是行名
$result = DB::select()->from('users')->join('roles','right outer')->on('roles.id', '=', DB::expr('1'));

转义

在资料库呼叫中,栏位和值是预设转义。在某些情况下,你会希望不要转义资料,DB 类别提供一个 DB::expr 方法来建立资料库表达式。如果你不想要一个值被转义,只要在一个资料库表达式包住它。

资料库表达式在处理像是 MySQL 的原生函式(如 COUNT)和预定义常数(如 DEFAULT)时特别有用。

// 设定一个栏位为它的预设
DB::update('users')->where('id', '=', 1)->set(array(
	'some_column' => DB::expr('DEFAULT'),
))->execute();

// SELECT COUNT(*) as count FROM `users`
$result = DB::select(DB::expr('COUNT(*) as count'))->from('users')->execute();

// 取得目前/第一笔结果
$result_arr = $result->current();

// 取得笔数
$count = $result_arr['count'];

赋值查询

查询建立器支援赋值查询,它是一种技术, 能让你在安全可靠的方法指派变数到你手写查询。

赋值查询藉由放置在你的查询中唯一可辨认的占位符运作。 赋值查询藉由放置在你的查询中唯一可辨认的占位符运作。当查询被编译执行时(你连接它时!), 查询建立器将以它们对应的值取代这些占位符。

你可以使用 FuelPHP 标准表示法定义占位符,它是一个以冒号前缀 (:变数名称)的字串。

$name = 'John'; // 设定我们想要连接的变数
$query = "SELECT * FROM users WHERE username = :name"; // 我们的查询

// 连接变数并执行查询,产生 SELECT * FROM users WHERE username = 'John'
$result = DB::query($query)->bind('name', $name)->execute();

变数藉由参照绑定,所以你可以轻易地在你的程式码中,定义你的查询和赋值, 并在稍后修改绑定的变数。

// 建立查询物件
$query = DB::query("SELECT * FROM users WHERE username = :name");

$name = 'unknown';                // 设定变数预设值
$query->bind('name', $name);     // 并连接到查询

// 在一些程式码之后,变更绑定的变数
$name = 'Sally';

// 连接变数并执行查询,产生 SELECT * FROM users WHERE username = 'Sally'
$result = $query->execute();

因为变数藉由参照绑定,你不能连接一个文字。 如果你这样做,将得到一个 "Cannot pass parameter 2 by reference" 例外!

// 这将产生一个例外!
$query = DB::query("SELECT * FROM users WHERE username = :name")->bind('name', 'value')->execute();

你可以使用 param() 方法指派值:

// 这会运作
$query = DB::query("SELECT * FROM users WHERE username = :name")->param('name', 'value')->execute();

最后,你可以使用 parameters() 方法,如果你想要混合两者的话:

// 建立查询物件
$query = DB::query("SELECT * FROM users WHERE username = :name AND state = :state");

$name = 'John'; // 设定我们想要连接的变数

// 连接变数和文字
$query->parameters(array('name' => &$name, 'state' => 'new'));

// 并执行查询,产生 SELECT * FROM users WHERE username = 'John' AND state = 'new'
$result = $query->execute();

有些框架使用问号做为占位符,这适用于它们,因为它们的赋值系统是定位的, 第一个问号被第一个绑定的变数取代,以此类推。 在 FuelPHP 中,赋值的顺序是不相关的, 在占位符和绑定的变数之间是一对一的连结, 这也意味着,你可以在单一查询中多次使用相同的占位符。

快取查询

查询建立器也支援快取查询的结果,以帮助你减低你的资料库存取。 为了实现此目标,它在幕后使用 Cache 类别, 但处理快取的取回和再生。
cached() 方法使用 3 个参数:到期时间(以秒为单位的快取有效期); 第二个参数为查询设定一个自订的键(预设是一个查询的 md5 杂凑); 一个布林可用来表示你不想要快取空结果。 使用一个自订快取键将能让你更易于手动删除特定查询, 及组合一组查询快取进特定的目录。

// 执行一个查询并快取它 1 小时
// 如果你下一次执行确切相同的查询,它将回传快取的结果。
// 这将发生在快取的 3600 秒内,否则将执行
// 并且产生另一次快取。
$query = DB::query("SELECT * FROM users")->cached(3600)->execute();

// 你可以指定一个键来处理快取结果的删除,如果你
// 知道该键将被更新和在它显示前需要被删除的话是有用的。
// 空查询结果将不会被快取。
$query = DB::query("SELECT * FROM users")->cached(3600, "foo.bar", false)->execute();

// 从快取删除前一个查询
Cache::delete("foo.bar");
// 或删除在 "foo" 目录中的所有快取
Cache::delete_all("foo");

// 预设情况下所有查询被放在 "db" 目录
// 因此,不手动设定其中的键,要删除所有查询快取
Cache::delete_all("db");